From 07e6ff5fcfe337bb65a7c3a4493a92a7761cf2ed Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 14 Apr 2002 09:44:16 +0000 Subject: Partly based on the work by mimir (Rafal Szczesniak ) this patch allows samba to correctly enumerate its trusted domains - by exaimining the keys in the secrets.tdb file. This patch has been tested with both NT4 and rpcclient/wbinfo, and adds some extra functionality to talloc and rpc_parse to allow it to deal with already unicode strings. Finally, this cleans up some const warnings that were in net_rpc.c by pushing another dash of const into the rpc client code. Andrew Bartlett (This used to be commit 0bdd94cb992b40942aaf2e5e0efd2868b4686296) --- source3/libsmb/cli_samr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 85a7375f99..f3560ede5d 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -971,7 +971,7 @@ NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *domain_pol, uint32 flags, - uint32 num_names, char **names, + uint32 num_names, const char **names, uint32 *num_rids, uint32 **rids, uint32 **rid_types) { -- cgit From 3a139656a336ac0b86632b9a32ed32ed85c969c0 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 14 Apr 2002 11:13:49 +0000 Subject: Added error string for STATUS_SOME_UNMAPPED (This used to be commit f736e115c00e02e3f131ccceb7769559dd4d908a) --- source3/libsmb/nterr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index b74dde9b14..faf5147fe2 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -534,6 +534,7 @@ 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 }, + { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, { NULL, NT_STATUS(0) } }; -- cgit From d0386372b2f491cd9281fc6466b1b5d2f5cf59a9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 14 Apr 2002 11:21:25 +0000 Subject: The cli_lsa_lookup_{names,sids} functions were returning useless information when one or more of the names/sids being queried were not resolvable. We now return a list the same length as the parameters passed instead of an array of just the resolvable names/sids. (This used to be commit 245468dbabb7c849ce423cc3cb586fa913d0adfe) --- source3/libsmb/cli_lsarpc.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 3216854608..1989169fd7 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -230,7 +230,7 @@ NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, int num_sids, DOM_SID *sids, - char ***domains, char ***names, uint32 **types, int *num_names) + char ***domains, char ***names, uint32 **types) { prs_struct qbuf, rbuf; LSA_Q_LOOKUP_SIDS q; @@ -274,13 +274,13 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_FILES_OPEN)) { + NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) { + /* An actual error occured */ goto done; } - /* Return output parameters */ if (r.mapped_count == 0) { @@ -288,28 +288,28 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, goto done; } - (*num_names) = r.mapped_count; - result = NT_STATUS_OK; - - if (!((*domains) = (char **)talloc(mem_ctx, sizeof(char *) * r.mapped_count))) { + if (!((*domains) = (char **)talloc(mem_ctx, sizeof(char *) * + num_sids))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) * r.mapped_count))) { + if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) * + num_sids))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - if (!((*types) = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.mapped_count))) { + if (!((*types) = (uint32 *)talloc(mem_ctx, sizeof(uint32) * + num_sids))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - for (i = 0; i < r.mapped_count; i++) { + for (i = 0; i < num_sids; i++) { fstring name, dom_name; uint32 dom_idx = t_names.name[i].domain_idx; @@ -348,8 +348,9 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, /** Lookup a list of names */ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, int num_names, const char **names, - DOM_SID **sids, uint32 **types, int *num_sids) + POLICY_HND *pol, int num_names, + const char **names, DOM_SID **sids, + uint32 **types) { prs_struct qbuf, rbuf; LSA_Q_LOOKUP_NAMES q; @@ -388,13 +389,14 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (!NT_STATUS_IS_OK(result)) { + if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != + NT_STATUS_V(STATUS_SOME_UNMAPPED)) { + /* An actual error occured */ goto done; } - /* Return output parameters */ if (r.mapped_count == 0) { @@ -402,22 +404,21 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, goto done; } - (*num_sids) = r.mapped_count; - result = NT_STATUS_OK; - - if (!((*sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * r.mapped_count)))) { + if (!((*sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * + num_names)))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - if (!((*types = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.mapped_count)))) { + if (!((*types = (uint32 *)talloc(mem_ctx, sizeof(uint32) * + num_names)))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - for (i = 0; i < r.mapped_count; i++) { + for (i = 0; i < num_names; i++) { DOM_RID2 *t_rids = r.dom_rid; uint32 dom_idx = t_rids[i].rid_idx; uint32 dom_rid = t_rids[i].rid; -- cgit From b5c61023ff666dcdfda59ebb0bd80fe42837d482 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Apr 2002 06:56:01 +0000 Subject: better handling of DOS LANMAN2.1 protocol (This used to be commit 7f923d738b94eef042b21e4d0143861755620d91) --- source3/libsmb/cliconnect.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8ddd116679..4ed2aae1f3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -34,6 +34,7 @@ prots[] = {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, {PROTOCOL_LANMAN1,"LANMAN1.0"}, {PROTOCOL_LANMAN2,"LM1.2X002"}, + {PROTOCOL_LANMAN2,"DOS LANMAN2.1"}, {PROTOCOL_LANMAN2,"Samba"}, {PROTOCOL_NT1,"NT LANMAN 1.0"}, {PROTOCOL_NT1,"NT LM 0.12"}, @@ -45,7 +46,7 @@ prots[] = do an old lanman2 style session setup ****************************************************************************/ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, - char *pass, int passlen) + char *pass, int passlen, const char *workgroup) { fstring pword; char *p; @@ -88,7 +89,10 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - p += clistr_push(cli, p, user, -1, STR_TERMINATE); + p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER); + p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); + p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); + p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); cli_send_smb(cli); @@ -591,7 +595,7 @@ BOOL cli_session_setup(struct cli_state *cli, /* if its an older server then we have to use the older request format */ if (cli->protocol < PROTOCOL_NT1) { - return cli_session_setup_lanman2(cli, user, pass, passlen); + return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup); } /* if no user is supplied then we have to do an anonymous connection. @@ -756,6 +760,10 @@ void cli_negprot_send(struct cli_state *cli) char *p; int numprots; + if (cli->protocol < PROTOCOL_NT1) { + cli->use_spnego = False; + } + memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ @@ -788,6 +796,10 @@ BOOL cli_negprot(struct cli_state *cli) int numprots; int plength; + if (cli->protocol < PROTOCOL_NT1) { + cli->use_spnego = False; + } + memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ @@ -822,7 +834,7 @@ BOOL cli_negprot(struct cli_state *cli) return(False); } - cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; + cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; if (cli->protocol >= PROTOCOL_NT1) { /* NT protocol */ @@ -848,6 +860,7 @@ BOOL cli_negprot(struct cli_state *cli) smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN); } } else if (cli->protocol >= PROTOCOL_LANMAN1) { + cli->use_spnego = False; cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); cli->sesskey = IVAL(cli->inbuf,smb_vwv6); @@ -860,6 +873,7 @@ BOOL cli_negprot(struct cli_state *cli) cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf)); } else { /* the old core protocol */ + cli->use_spnego = False; cli->sec_mode = 0; cli->serverzone = TimeDiff(time(NULL)); } -- cgit From 37d67c3345e7016cc5e1626e9d0c4ffdebc596fb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Apr 2002 17:34:38 +0000 Subject: libsmb/cli_netlogon.c: Fixed confusing debug messages. param/loadparm.c: Added missing debugs that would have helped me find a misconfiguration I lost a day on.... Jeremy. (This used to be commit 6e9572379784c77f3c4e6a95e18a9641880a8ffc) --- source3/libsmb/cli_netlogon.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 125590b6d3..12651966d7 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -51,7 +51,7 @@ NTSTATUS new_cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, /* create and send a MSRPC command with api NET_REQCHAL */ - DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n", + DEBUG(4,("new_cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n", cli->desthost, global_myname, credstr(clnt_chal->data))); /* store the parameters */ @@ -108,7 +108,7 @@ NTSTATUS new_cli_net_auth2(struct cli_state *cli, /* create and send a MSRPC command with api NET_AUTH2 */ - DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", + DEBUG(4,("new_cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname, credstr(cli->clnt_cred.challenge.data), neg_flags)); @@ -147,7 +147,7 @@ NTSTATUS new_cli_net_auth2(struct cli_state *cli, /* * Server replied with bad credential. Fail. */ - DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \ + DEBUG(0,("new_cli_net_auth2: server %s replied with bad credential (bad machine \ password ?).\n", cli->desthost )); result = NT_STATUS_ACCESS_DENIED; goto done; @@ -180,7 +180,7 @@ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, result = new_cli_net_req_chal(cli, &clnt_chal, &srv_chal); if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("cli_nt_setup_creds: request challenge failed\n")); + DEBUG(0,("new_cli_nt_setup_creds: request challenge failed\n")); return result; } -- cgit From dcb572e0b26858f58ddcf5cac1c94be31cda844d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 19 Apr 2002 00:16:18 +0000 Subject: fixed a namequery bug caused by my recent string length patches (This used to be commit b2329039d255928faf53474ee7ab06b6353b9fbe) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 7928d44652..c578df6621 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -191,7 +191,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t if (i == count) goto done; - pull_ascii(name, status[i].name, 15, 0, STR_TERMINATE); + pull_ascii(name, status[i].name, 15, -1, STR_TERMINATE); result = True; done: -- cgit From 0fb9ea9fa45d28ea6660bab09998e704fd6502f8 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Mon, 22 Apr 2002 03:08:33 +0000 Subject: My seven-year-old daughter calls me 'Captain Pedantic'. I don't know which is freakier... the name or the fact that a seven-year-old knows what it means. Small change to correct the value we place in the DGM_LENGTH field of NBT Datagram messages. We have been counting the full datagram, but it's fairly clear in the RFCs that we should only count the source name, destination name, and payload. We've been overcharging by 14 bytes (the size of the NBT DGM header). This fix brings us in line with what Windows does, and what the RFCs say should be done. I'm a little surprised that this didn't cause any bugs or error messages. I guess no one actually checks this field. (This used to be commit 3156c020e5b6f12a448d58669977ad4449789460) --- source3/libsmb/nmblib.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index c78946fa09..9a37b4252a 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -766,6 +766,14 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) 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) { @@ -795,8 +803,11 @@ static int build_dgram(char *buf,struct packet_struct *p) memcpy(ubuf+offset,dgram->data,dgram->datasize); offset += dgram->datasize; - /* automatically set the dgm_length */ - dgram->header.dgm_length = offset; + /* 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); -- cgit From f2843dec43a4f239a01e167dc322e9808c6e4163 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 24 Apr 2002 05:36:40 +0000 Subject: Added constant and message for invalid security descriptor dos error. (This used to be commit 0827bd4184256a87d6cf6c58bc314309503da7be) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index adc001bf29..116a54e76f 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -65,6 +65,7 @@ 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_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { NULL, W_ERROR(0) } }; -- cgit From 236d5effaccd563fda075577eed05db02ad55889 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 7 May 2002 06:16:44 +0000 Subject: DOS error 1307 is returned when an invalid owner for a security descriptor is detected. (This used to be commit 0377448b8c3e2bd8d5bc9f49a585292dc5c5b5a1) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 116a54e76f..02db625685 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -66,6 +66,7 @@ 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_INVALID_OWNER", WERR_INVALID_OWNER }, { NULL, W_ERROR(0) } }; -- cgit From 099b006c3f0ac1b7cda973121d226f30452711ec Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 7 May 2002 06:28:27 +0000 Subject: Added cli_spoolss_enumjobs() function. (This used to be commit aaa996355287fcd86873697f51a069ccb5a908b9) --- source3/libsmb/cli_spoolss.c | 49 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index cf356ef815..0458b29d54 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1534,12 +1534,36 @@ done: return result; } +static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, + uint32 num_jobs, JOB_INFO_1 **jobs) +{ + uint32 i; + + *jobs = (JOB_INFO_1 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_1)); + buffer->prs.data_offset = 0; + + for (i = 0; i < num_jobs; i++) + smb_io_job_info_1("", buffer, &((*jobs)[i]), 0); +} + +static void decode_jobs_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, + uint32 num_jobs, JOB_INFO_2 **jobs) +{ + uint32 i; + + *jobs = (JOB_INFO_2 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_2)); + buffer->prs.data_offset = 0; + + for (i = 0; i < num_jobs; i++) + smb_io_job_info_2("", buffer, &((*jobs)[i]), 0); +} + /* Enumerate jobs */ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 offered, uint32 *needed, - POLICY_HND *hnd, uint32 firstjob, uint32 numofjobs, - uint32 level) + POLICY_HND *hnd, uint32 level, uint32 firstjob, + uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr) { prs_struct qbuf, rbuf; SPOOL_Q_ENUMJOBS q; @@ -1559,7 +1583,7 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ - make_spoolss_q_enumjobs(&q, hnd, firstjob, numofjobs, level, &buffer, + make_spoolss_q_enumjobs(&q, hnd, firstjob, num_jobs, level, &buffer, offered); /* Marshall data and send request */ @@ -1580,6 +1604,25 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (needed) *needed = r.needed; + if (!W_ERROR_IS_OK(r.status)) + goto done; + + *returned = r.returned; + + switch(level) { + case 1: + decode_jobs_1(mem_ctx, r.buffer, r.returned, + &ctr->job.job_info_1); + break; + case 2: + decode_jobs_2(mem_ctx, r.buffer, r.returned, + &ctr->job.job_info_2); + break; + default: + DEBUG(3, ("unsupported info level %d", level)); + break; + } + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); -- cgit From 26b0e0b478da99f4296c99c6e55ced26b44e591b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 8 May 2002 05:48:32 +0000 Subject: Added client side spoolss rpc commands for startpageprinter, endpageprinter, setjob and getjob. (This used to be commit d091a9d300c70b708218067d355c8282a6f14ab6) --- source3/libsmb/cli_spoolss.c | 200 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 0458b29d54..44bebedb09 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1630,4 +1630,204 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Set job */ + +WERROR cli_spoolss_setjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, uint32 jobid, uint32 level, + uint32 command) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_SETJOB q; + SPOOL_R_SETJOB r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_setjob(&q, hnd, jobid, level, command); + + /* Marshall data and send request */ + + if (!spoolss_io_q_setjob("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_SETJOB, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_setjob("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Get job */ + +WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + POLICY_HND *hnd, uint32 jobid, uint32 level, + JOB_INFO_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_GETJOB q; + SPOOL_R_GETJOB r; + WERROR result = W_ERROR(ERRgeneral); + NEW_BUFFER buffer; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + init_buffer(&buffer, offered, mem_ctx); + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_getjob(&q, hnd, jobid, level, &buffer, offered); + + /* Marshall data and send request */ + + if (!spoolss_io_q_getjob("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_GETJOB, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_getjob("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + if (needed) + *needed = r.needed; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + switch(level) { + case 1: + decode_jobs_1(mem_ctx, r.buffer, 1, &ctr->job.job_info_1); + break; + case 2: + decode_jobs_2(mem_ctx, r.buffer, 1, &ctr->job.job_info_2); + break; + default: + DEBUG(3, ("unsupported info level %d", level)); + break; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Startpageprinter */ + +WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_STARTPAGEPRINTER q; + SPOOL_R_STARTPAGEPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_startpageprinter(&q, hnd); + + /* Marshall data and send request */ + + if (!spoolss_io_q_startpageprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_STARTPAGEPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_startpageprinter("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Endpageprinter */ + +WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ENDPAGEPRINTER q; + SPOOL_R_ENDPAGEPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_endpageprinter(&q, hnd); + + /* Marshall data and send request */ + + if (!spoolss_io_q_endpageprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ENDPAGEPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_endpageprinter("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ -- cgit From 9bd8bf5d12f8a94d355e97ccf1ddace09d9d8254 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 13 May 2002 03:25:23 +0000 Subject: RPC client function for startdocprinter and enddocprinter. (This used to be commit 38de5025fb1f6396e456e26bfb071223da247f03) --- source3/libsmb/cli_spoolss.c | 103 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 44bebedb09..f3bc96fb25 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1742,7 +1742,8 @@ WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/* Startpageprinter */ +/* Startpageprinter. Sent to notify the spooler when a page is about to be + sent to a printer. */ WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd) @@ -1786,7 +1787,8 @@ WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/* Endpageprinter */ +/* Endpageprinter. Sent to notify the spooler when a page has finished + being sent to a printer. */ WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd) @@ -1830,4 +1832,101 @@ WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Startdocprinter. Sent to notify the spooler that a document is about + to be spooled for printing. */ + +WERROR cli_spoolss_startdocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, char *docname, + char *outputfile, char *datatype, + uint32 *jobid) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_STARTDOCPRINTER q; + SPOOL_R_STARTDOCPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + uint32 level = 1; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_startdocprinter(&q, hnd, level, docname, outputfile, + datatype); + + /* Marshall data and send request */ + + if (!spoolss_io_q_startdocprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_STARTDOCPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_startdocprinter("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + if (W_ERROR_IS_OK(result)) + *jobid = r.jobid; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Enddocprinter. Sent to notify the spooler that a document has finished + being spooled. */ + +WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ENDDOCPRINTER q; + SPOOL_R_ENDDOCPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_enddocprinter(&q, hnd); + + /* Marshall data and send request */ + + if (!spoolss_io_q_enddocprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ENDDOCPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_enddocprinter("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ -- cgit From 55cc5f4c08ef1eab61cd3d7f0f134c24276cf94a Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 14 May 2002 05:26:50 +0000 Subject: Added getprinterdata and enumprinterdata rpc client routines. The setprinterdata routine was rewritten slightly to take more arguments. (This used to be commit a9a5702c88ea9c4a6a9197cf4e3444b26be858cc) --- source3/libsmb/cli_spoolss.c | 228 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 186 insertions(+), 42 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index f3bc96fb25..6f1024e577 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1492,48 +1492,6 @@ WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/********************************************************************************* - Win32 API - SetPrinterData() - ********************************************************************************/ - -WERROR cli_spoolss_setprinterdata (struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, char* valname, char* value) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETPRINTERDATA q; - SPOOL_R_SETPRINTERDATA r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - - /* write the request */ - make_spoolss_q_setprinterdata(&q, mem_ctx, pol, valname, value); - - /* Marshall data and send request */ - if (!spoolss_io_q_setprinterdata ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - if (spoolss_io_r_setprinterdata ("", &r, &rbuf, 0)) - goto done; - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, uint32 num_jobs, JOB_INFO_1 **jobs) { @@ -1929,4 +1887,190 @@ WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Get printer data */ + +WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + POLICY_HND *hnd, char *valuename, + uint32 *data_type, char **data, + uint32 *data_size) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_GETPRINTERDATA q; + SPOOL_R_GETPRINTERDATA r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_getprinterdata(&q, hnd, valuename, offered); + + /* Marshall data and send request */ + + if (!spoolss_io_q_getprinterdata("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATA, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_getprinterdata("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (needed) + *needed = r.needed; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + /* Return output parameters */ + + if (data_type) + *data_type = r.type; + + if (data) { + *data = (char *)talloc(mem_ctx, r.needed); + memcpy(*data, r.data, r.needed); + } + + if (data_size) + *data_size = r.needed; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Set printer data */ + +WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, char *value, + uint32 data_type, char *data, + uint32 data_size) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_SETPRINTERDATA q; + SPOOL_R_SETPRINTERDATA r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_setprinterdata(&q, hnd, value, data, data_size); + + /* Marshall data and send request */ + + if (!spoolss_io_q_setprinterdata("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_setprinterdata("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Enum printer data */ + +WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, uint32 ndx, + uint32 value_offered, uint32 data_offered, + uint32 *value_needed, uint32 *data_needed, + char **value, uint32 *data_type, char **data, + uint32 *data_size) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ENUMPRINTERDATA q; + SPOOL_R_ENUMPRINTERDATA r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_enumprinterdata(&q, hnd, ndx, value_offered, data_offered); + + /* Marshall data and send request */ + + if (!spoolss_io_q_enumprinterdata("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERDATA, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_enumprinterdata("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + /* Return data */ + + if (value_needed) + *value_needed = r.realvaluesize; + + if (data_needed) + *data_needed = r.realdatasize; + + if (data_type) + *data_type = r.type; + + if (value) { + fstring the_value; + + rpcstr_pull(the_value, r.value, sizeof(the_value), -1, + STR_TERMINATE); + + *value = talloc_strdup(mem_ctx, the_value); + } + + if (data) + *data = talloc_memdup(mem_ctx, r.data, r.realdatasize); + + if (data_size) + *data_size = r.realdatasize; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ -- cgit From 3d95426f2c88b4bc3914d8bf894c990039db7ea5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 14 May 2002 06:37:54 +0000 Subject: Added writeprinter rpc command. (This used to be commit a1934a7a8eda592e283a01014280ddb373564927) --- source3/libsmb/cli_spoolss.c | 49 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 6f1024e577..575817fb37 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -2073,4 +2073,53 @@ WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Write data to printer */ + +WERROR cli_spoolss_writeprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, uint32 data_size, char *data, + uint32 *num_written) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_WRITEPRINTER q; + SPOOL_R_WRITEPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_writeprinter(&q, hnd, data_size, data); + + /* Marshall data and send request */ + + if (!spoolss_io_q_writeprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_WRITEPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_writeprinter("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + if (num_written) + *num_written = r.buffer_written; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ -- cgit From af451af22f745d56bb92f0dbdd270f7fd024ef0d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 14 May 2002 07:21:57 +0000 Subject: Added deleteprinterdata client rpc. (This used to be commit 217ae50acd8cf088e268e7d2a6a7c192aca9e2f1) --- source3/libsmb/cli_spoolss.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 575817fb37..754b7b20a5 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -2122,4 +2122,49 @@ WERROR cli_spoolss_writeprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Delete printer data */ + +WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, char *valuename) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_DELETEPRINTERDATA q; + SPOOL_R_DELETEPRINTERDATA r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_deleteprinterdata(&q, hnd, valuename); + + /* Marshall data and send request */ + + if (!spoolss_io_q_deleteprinterdata("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERDATA, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_deleteprinterdata("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ -- cgit From 6ee4366093b24251aa52c272512b2efacb9582d8 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 17 May 2002 03:37:37 +0000 Subject: Changes to allow head to translate NMB flags ... (This used to be commit c986a19cde0dfa96b512eb24d873203981e68c48) --- source3/libsmb/namequery.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index c578df6621..85f33aeda4 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -305,7 +305,7 @@ BOOL name_register(int fd, const char *name, int name_type, ****************************************************************************/ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse, - struct in_addr to_ip, int *count) + struct in_addr to_ip, int *count, int *flags) { BOOL found=False; int i, retries = 3; @@ -318,6 +318,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type, memset((char *)&p,'\0',sizeof(p)); (*count) = 0; + (*flags) = 0; nmb->header.name_trn_id = generate_trn_id(); nmb->header.opcode = 0; @@ -440,6 +441,19 @@ struct in_addr *name_query(int fd,const char *name,int name_type, 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 @@ -670,10 +684,11 @@ BOOL name_resolve_bcast(const char *name, int name_type, */ 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); + True, sendto_ip, return_count, &flags); if(*return_ip_list != NULL) { close(sock); return True; @@ -726,6 +741,7 @@ static BOOL resolve_wins(const char *name, int name_type, DEBUG(3, ("resolve_wins: WINS server == <%s>\n", inet_ntoa(wins_ip)) ); if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) { + int flags; sock = open_socket_in( SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True ); @@ -733,7 +749,7 @@ static BOOL resolve_wins(const char *name, int name_type, *return_iplist = name_query( sock, name, name_type, False, True, wins_ip, - return_count); + return_count, &flags); if(*return_iplist != NULL) { close(sock); return True; -- cgit From 7a6a5bc6d758d278e4b39806978ea2b3eeaaaf9d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 17 May 2002 05:33:48 +0000 Subject: NT sends the server name prepended with \\ for a enumerate printers RPC call so we probably should as well. (This used to be commit 39c0218e5b4132e60401c2fc25fcbc88be94f87f) --- source3/libsmb/cli_spoolss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 754b7b20a5..28f4f481fa 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -420,8 +420,8 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, ZERO_STRUCT(q); ZERO_STRUCT(r); - fstrcpy (server, cli->desthost); - strupper (server); + slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); + strupper (server); /* Initialise input parameters */ -- cgit From eed5094264945ca8ccf47030375cc56808ae8ea3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 17 May 2002 12:42:39 +0000 Subject: This removes --with-ssl from Samba. This option was badly maintained, useless and confused our users and distirbutors. (its SSL, therfore it must be good...) No windows client uses this protocol without help from an SSL tunnel. I can't see any reason why setting up a unix-side SSL wrapper would be any more difficult than the > 10 config options this mess added to samba in any case. On the Samba client end, I think the LIBSMB_PROG hack should be sufficient to start stunnel on the unix side. We might extend this to take %i and %p (IP and port) if there is demand. Andrew Bartlett (This used to be commit b04561d3fd3ee732877790fb4193b20ad72a75f8) --- source3/libsmb/cliconnect.c | 13 ------------- source3/libsmb/clientgen.c | 4 ---- 2 files changed, 17 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4ed2aae1f3..ec2c33f419 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -920,10 +920,6 @@ BOOL cli_session_request(struct cli_state *cli, _smb_setlen(cli->outbuf,len); SCVAL(cli->outbuf,0,0x81); -#ifdef WITH_SSL -retry: -#endif /* WITH_SSL */ - cli_send_smb(cli); DEBUG(5,("Sent session request\n")); @@ -969,15 +965,6 @@ retry: } } /* C. Hoch 9/14/95 End */ -#ifdef WITH_SSL - if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ - if (!sslutil_fd_is_ssl(cli->fd)){ - if (sslutil_connect(cli->fd) == 0) - goto retry; - } - } -#endif /* WITH_SSL */ - if (CVAL(cli->inbuf,0) != 0x82) { /* This is the wrong place to put the error... JRA. */ cli->rap_error = CVAL(cli->inbuf,4); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ba7a327344..677a0f4220 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -247,10 +247,6 @@ void cli_shutdown(struct cli_state *cli) if (cli->mem_ctx) talloc_destroy(cli->mem_ctx); -#ifdef WITH_SSL - if (cli->fd != -1) - sslutil_disconnect(cli->fd); -#endif /* WITH_SSL */ if (cli->fd != -1) close(cli->fd); allocated = cli->allocated; -- cgit From 3fe27b7f9df7d2bb2f7799fd46b79928f0e614b0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 17 May 2002 13:49:01 +0000 Subject: A few more trusted domains updates from mimir. I think we may still need to look at our server enumeration code, but other than that, its much better in the tree than out. Andrew Bartlett (This used to be commit d57a1b4629d12a0374cc6d74dfc6f5d4793fcef8) --- source3/libsmb/cli_lsarpc.c | 31 ++++++++++++++++++++++--------- source3/libsmb/nterr.c | 1 + 2 files changed, 23 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 1989169fd7..8eaf6da2ec 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -5,7 +5,8 @@ Copyright (C) Andrew Tridgell 1992-1997,2000, Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, Copyright (C) Paul Ashton 1997,2000, - Copyright (C) Elrond 2000. + Copyright (C) Elrond 2000, + 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 @@ -537,12 +538,25 @@ NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/** Enumerate list of trusted domains */ +/** + * Enumerate list of trusted domains + * + * @param cli client state (cli_state) structure of the connection + * @param mem_ctx memory context + * @param pol opened lsa policy handle + * @param enum_ctx enumeration context ie. index of first returned domain entry + * @param pref_num_domains preferred max number of entries returned in one response + * @param num_domains total number of trusted domains returned by response + * @param domain_names returned trusted domain names + * @param domain_sids returned trusted domain sids + * + * @return nt status code of response + **/ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 *enum_ctx, - uint32 *num_domains, char ***domain_names, - DOM_SID **domain_sids) + uint32 *pref_num_domains, uint32 *num_domains, + char ***domain_names, DOM_SID **domain_sids) { prs_struct qbuf, rbuf; LSA_Q_ENUM_TRUST_DOM q; @@ -560,7 +574,7 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Marshall data and send request */ - init_q_enum_trust_dom(&q, pol, *enum_ctx, 0xffffffff); + init_q_enum_trust_dom(&q, pol, *enum_ctx, *pref_num_domains); if (!lsa_io_q_enum_trust_dom("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_ENUMTRUSTDOM, &qbuf, &rbuf)) { @@ -577,16 +591,15 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_NO_MORE_ENTRIES)) { + if (!NT_STATUS_IS_OK(result) && + !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) && + !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { /* An actual error ocured */ goto done; } - result = NT_STATUS_OK; - /* Return output parameters */ if (r.num_domains) { diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index faf5147fe2..e2da6318e1 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -534,6 +534,7 @@ 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 }, + { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, { NULL, NT_STATUS(0) } }; -- cgit From ac03889168cc5b97651ee5e4300ce50210de8800 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 18 May 2002 13:19:38 +0000 Subject: Move client_receive_smb to clientgen.c as a static, as proposed by Elrond. (only function that used it was unused, and this helps bring TNG and HEAD closer) Its also cleaner. Andrew Bartlett (This used to be commit 78f47c83332a6408a718a3dee45645935638b364) --- source3/libsmb/clientgen.c | 35 ++++++++++++++++++++++++++++ source3/libsmb/clireadwrite.c | 53 ++++++++++++++++++++++--------------------- 2 files changed, 62 insertions(+), 26 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 677a0f4220..dee86b2b05 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -31,6 +31,41 @@ int cli_set_port(struct cli_state *cli, int port) return port; } +/**************************************************************************** + read an smb from a fd ignoring all keepalive packets. Note that the buffer + *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. + The timeout is in milliseconds + + This is exactly the same as receive_smb except that it never returns + a session keepalive packet (just as receive_smb used to do). + receive_smb was changed to return keepalives as the oplock processing means this call + should never go into a blocking read. +****************************************************************************/ + +static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) +{ + BOOL ret; + + for(;;) + { + ret = receive_smb(fd, buffer, timeout); + + if (!ret) + { + DEBUG(10,("client_receive_smb failed\n")); + show_msg(buffer); + return ret; + } + + /* Ignore session keepalive packets. */ + if(CVAL(buffer,0) != SMBkeepalive) + break; + } + show_msg(buffer); + return ret; +} + + /**************************************************************************** recv an smb ****************************************************************************/ diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 0a9569fc69..6fce1c039b 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -48,31 +48,6 @@ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, return cli_send_smb(cli); } -/**************************************************************************** -Issue a single SMBreadraw and don't wait for a reply. -****************************************************************************/ - -static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset, - size_t size, int i) -{ - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,10,0,True); - - SCVAL(cli->outbuf,smb_com,SMBreadbraw); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,fnum); - SIVAL(cli->outbuf,smb_vwv1,offset); - SSVAL(cli->outbuf,smb_vwv2,size); - SSVAL(cli->outbuf,smb_vwv3,size); - SSVAL(cli->outbuf,smb_mid,cli->mid + i); - - return cli_send_smb(cli); -} - /**************************************************************************** Read size bytes at offset offset using SMBreadX. ****************************************************************************/ @@ -152,6 +127,32 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ return total; } +#if 0 /* relies on client_recieve_smb(), now a static in libsmb/clientgen.c */ +/**************************************************************************** +Issue a single SMBreadraw and don't wait for a reply. +****************************************************************************/ + +static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset, + size_t size, int i) +{ + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,10,0,True); + + SCVAL(cli->outbuf,smb_com,SMBreadbraw); + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,fnum); + SIVAL(cli->outbuf,smb_vwv1,offset); + SSVAL(cli->outbuf,smb_vwv2,size); + SSVAL(cli->outbuf,smb_vwv3,size); + SSVAL(cli->outbuf,smb_mid,cli->mid + i); + + return cli_send_smb(cli); +} + /**************************************************************************** Tester for the readraw call. ****************************************************************************/ @@ -213,7 +214,7 @@ ssize_t cli_readraw(struct cli_state *cli, int fnum, char *buf, off_t offset, si return total; } - +#endif /**************************************************************************** issue a single SMBwrite and don't wait for a reply ****************************************************************************/ -- cgit From e46a6ecc697418ad7eb9aedb1610d1fbbe419029 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 23 May 2002 14:02:17 +0000 Subject: Given Jeremy's positive response, and a lack of one from tpot, I'll commit this: More code cleanup - this lot a bit more dodgy than the last: The aim is to trim pwd_cache down to size. Its overly complex, and a pain to deal with. With a header comment like this: 'obfusticaion is planned' I think it deserved to die (at least partly). This was being done to allow 'cli_establish_connection' to die - its functionality has been replaced by cli_full_connection(), which does not duplicate code everywhere for creating names etc. This also removes the little 'init' fucntions for the various pipes, becouse they were only used in one place, and even then it was dodgy. (I've reworked smbcacls not to use anonymous connections any more, as this will (should) fail with a 'restrict anonymous' PDC). This allowed me to remove cli_pipe_util.c, which was calling cli_establish_connection. tpot: I'm not sure what direction you were going with the client stuff, and you may well have been wanting the init functions. If thats the case, give me a yell and I'll reimplement them against cli_full_connection. Andrew Bartlett (This used to be commit fa67e4626bed623333c571e76e06ccd52cba5cc5) --- source3/libsmb/cli_dfs.c | 8 --- source3/libsmb/cli_lsarpc.c | 13 ---- source3/libsmb/cli_netlogon.c | 9 --- source3/libsmb/cli_pipe_util.c | 82 ----------------------- source3/libsmb/cli_reg.c | 9 --- source3/libsmb/cli_samr.c | 8 --- source3/libsmb/cli_spoolss.c | 14 ---- source3/libsmb/cli_srvsvc.c | 9 --- source3/libsmb/cli_wkssvc.c | 18 ----- source3/libsmb/cliconnect.c | 148 +---------------------------------------- source3/libsmb/pwd_cache.c | 135 +++++-------------------------------- 11 files changed, 19 insertions(+), 434 deletions(-) delete mode 100644 source3/libsmb/cli_pipe_util.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_dfs.c b/source3/libsmb/cli_dfs.c index 312275926c..7fc27b9c3b 100644 --- a/source3/libsmb/cli_dfs.c +++ b/source3/libsmb/cli_dfs.c @@ -20,14 +20,6 @@ #include "includes.h" -/* Opens a SMB connection to the netdfs pipe */ - -struct cli_state *cli_dfs_initialise(struct cli_state *cli, char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_NETDFS, creds); -} - /* Query DFS support */ NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx, diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 8eaf6da2ec..9d07eb1d1e 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -38,19 +38,6 @@ * security authority", which is half of a password database. **/ -/** Opens a SMB connection and connects to the LSARPC pipe. - * - * @param cli Uninitialised client handle. - * @param system_name NETBIOS name of the machine to connect to. - * @param creds User credentials to connect as. - * @returns Initialised client handle. - */ -struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_LSARPC, creds); -} - /** Open a LSA policy handle * * @param cli Handle on an initialised SMB connection */ diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 12651966d7..765f19a5fe 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -25,15 +25,6 @@ #include "includes.h" -/* Opens a SMB connection to the netlogon pipe */ - -struct cli_state *cli_netlogon_initialise(struct cli_state *cli, - char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_NETLOGON, creds); -} - /* LSA Request Challenge. Sends our challenge to server, then gets server response. These are used to generate the credentials. */ diff --git a/source3/libsmb/cli_pipe_util.c b/source3/libsmb/cli_pipe_util.c deleted file mode 100644 index de1c832e44..0000000000 --- a/source3/libsmb/cli_pipe_util.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client utility functions - Copyright (C) Tim Potter 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" - -/** \defgroup rpc_client RPC Client routines - */ - -/* Opens a SMB connection to a named pipe */ - -struct cli_state *cli_pipe_initialise(struct cli_state *cli, char *system_name, - char *pipe_name, - struct ntuser_creds *creds) -{ - struct in_addr dest_ip; - struct nmb_name calling, called; - fstring dest_host; - extern pstring global_myname; - struct ntuser_creds anon; - - /* Initialise cli_state information */ - - if (!cli_initialise(cli)) { - return NULL; - } - - if (!creds) { - ZERO_STRUCT(anon); - anon.pwd.null_pwd = 1; - creds = &anon; - } - - cli_init_creds(cli, creds); - - /* Establish a SMB connection */ - - if (!resolve_srv_name(system_name, dest_host, &dest_ip)) { - return NULL; - } - - make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); - make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); - - if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling, - &called, "IPC$", "IPC", False, True)) { - return NULL; - } - - /* Open a NT session thingy */ - - if (!cli_nt_session_open(cli, pipe_name)) { - cli_shutdown(cli); - return NULL; - } - - return cli; -} - -/* Shut down a SMB connection to the SAMR pipe */ - -void cli_pipe_shutdown(struct cli_state *cli) -{ - if (cli->fd != -1) cli_ulogoff(cli); - cli_shutdown(cli); -} diff --git a/source3/libsmb/cli_reg.c b/source3/libsmb/cli_reg.c index c09ccabb29..aaf18882f7 100644 --- a/source3/libsmb/cli_reg.c +++ b/source3/libsmb/cli_reg.c @@ -25,15 +25,6 @@ #include "includes.h" -/* Opens a SMB connection to the WINREG pipe */ - -struct cli_state *cli_winreg_initialise(struct cli_state *cli, - char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_WINREG, creds); -} - /* Shutdown a server */ NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx, diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index f3560ede5d..9a332aa99e 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -24,14 +24,6 @@ #include "includes.h" -/* Opens a SMB connection to the SAMR pipe */ - -struct cli_state *cli_samr_initialise(struct cli_state *cli, char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_SAMR, creds); -} - /* Connect to SAMR database */ NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 28f4f481fa..5e33e00c68 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -31,20 +31,6 @@ * @{ **/ -/** Opens a SMB connection and connects to the SPOOLSS pipe. - * - * @param cli Uninitialised client handle. - * @param system_name NETBIOS name of the machine to connect to. - * @param creds User credentials to connect as. - * @returns Initialised client handle. - */ -struct cli_state *cli_spoolss_initialise(struct cli_state *cli, - char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_SPOOLSS, creds); -} - /********************************************************************** Initialize a new spoolss buff for use by a client rpc **********************************************************************/ diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 9d33149540..b5b4478684 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -22,15 +22,6 @@ #include "includes.h" -/* Opens a SMB connection to the svrsvc pipe */ - -struct cli_state *cli_svrsvc_initialise(struct cli_state *cli, - char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_SRVSVC, creds); -} - NTSTATUS cli_srvsvc_net_srv_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 switch_value, SRV_INFO_CTR *ctr) diff --git a/source3/libsmb/cli_wkssvc.c b/source3/libsmb/cli_wkssvc.c index 2a84e6b698..756ff61e5b 100644 --- a/source3/libsmb/cli_wkssvc.c +++ b/source3/libsmb/cli_wkssvc.c @@ -23,24 +23,6 @@ #include "includes.h" -/** - * Opens a SMB connection to the wkssvc pipe - * - * @param cli client structure (not yet initialised) - * @param system_name called rpc server name - * @param creds user credentials - * - * @return client structure with opened pipe - **/ - -struct cli_state *cli_wkssvc_initialise(struct cli_state *cli, - char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_WKSSVC, creds); -} - - /** * WksQueryInfo rpc call (like query for server's capabilities) * diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ec2c33f419..f41c3b7701 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1027,152 +1027,6 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) return True; } -/**************************************************************************** -establishes a connection right up to doing tconX, password in cache. -****************************************************************************/ -BOOL cli_establish_connection(struct cli_state *cli, - char *dest_host, struct in_addr *dest_ip, - struct nmb_name *calling, struct nmb_name *called, - char *service, char *service_type, - BOOL do_shutdown, BOOL do_tcon) -{ - DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", - nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip), - cli->user_name, cli->domain)); - - /* establish connection */ - - if ((!cli->initialised)) - { - return False; - } - - /* cli_establish_connection() can't handle spnego yet. Once we get rid of - pwd_cache and other horrors we can get rid of this */ - cli->use_spnego = False; - - if (cli->fd == -1) - { - if (!cli_connect(cli, dest_host, dest_ip)) - { - DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", - nmb_namestr(called), inet_ntoa(*dest_ip))); - return False; - } - } - - if (!cli_session_request(cli, calling, called)) - { - DEBUG(1,("failed session request\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - if (!cli_negprot(cli)) - { - DEBUG(1,("failed negprot\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - if (cli->pwd.cleartext || cli->pwd.null_pwd) - { - fstring passwd; - int pass_len; - - if (cli->pwd.null_pwd) - { - /* attempt null session */ - passwd[0] = 0; - pass_len = 1; - } - else - { - /* attempt clear-text session */ - pwd_get_cleartext(&(cli->pwd), passwd); - pass_len = strlen(passwd); - } - - /* attempt clear-text session */ - if (!cli_session_setup(cli, cli->user_name, - passwd, pass_len, - NULL, 0, - cli->domain)) - { - DEBUG(1,("failed session setup\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - if (do_tcon) - { - if (!cli_send_tconX(cli, service, service_type, - (char*)passwd, strlen(passwd))) - { - DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - } - } - else - { - /* attempt encrypted session */ - unsigned char nt_sess_pwd[24]; - unsigned char lm_sess_pwd[24]; - - /* creates (storing a copy of) and then obtains a 24 byte password OWF */ - pwd_make_lm_nt_owf(&(cli->pwd), cli->secblob.data); - pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd); - - /* attempt encrypted session */ - if (!cli_session_setup(cli, cli->user_name, - (char*)lm_sess_pwd, sizeof(lm_sess_pwd), - (char*)nt_sess_pwd, sizeof(nt_sess_pwd), - cli->domain)) - { - DEBUG(1,("failed session setup\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - DEBUG(1,("session setup ok\n")); - - if (*cli->server_domain || *cli->server_os || *cli->server_type) - { - DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", - cli->server_domain, - cli->server_os, - cli->server_type)); - } - - if (do_tcon) - { - if (!cli_send_tconX(cli, service, service_type, - (char*)nt_sess_pwd, sizeof(nt_sess_pwd))) - { - DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - } - } - - if (do_shutdown) - cli_shutdown(cli); - - return True; -} - /* Initialise client credentials for authenticated pipe access */ static void init_creds(struct ntuser_creds *creds, char* username, @@ -1230,7 +1084,7 @@ again: DEBUG(3,("Connecting to host=%s share=%s\n", dest_host, service)); if (!cli_connect(cli, dest_host, &ip)) { - DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", + DEBUG(1,("cli_full_connection: failed to connect to %s (%s)\n", nmb_namestr(&called), inet_ntoa(*dest_ip))); cli_shutdown(cli); return NT_STATUS_UNSUCCESSFUL; diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 7d1185d9a7..8b79788fed 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -24,7 +24,7 @@ Initialises a password structure. ****************************************************************************/ -void pwd_init(struct pwd_info *pwd) +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)); @@ -38,89 +38,21 @@ void pwd_init(struct pwd_info *pwd) } /**************************************************************************** - Returns NULL password flag. -****************************************************************************/ - -BOOL pwd_is_nullpwd(const struct pwd_info *pwd) -{ - return pwd->null_pwd; -} - -/**************************************************************************** - Compares two passwords. hmm, not as trivial as expected. hmm. -****************************************************************************/ - -BOOL pwd_compare(const struct pwd_info *pwd1, const struct pwd_info *pwd2) -{ - if (pwd1->cleartext && pwd2->cleartext) { - if (strequal(pwd1->password, pwd2->password)) - return True; - } - if (pwd1->null_pwd && pwd2->null_pwd) - return True; - - if (!pwd1->null_pwd && !pwd2->null_pwd && - !pwd1->cleartext && !pwd2->cleartext) { -#ifdef DEBUG_PASSWORD - DEBUG(100,("pwd compare: nt#\n")); - dump_data(100, pwd1->smb_nt_pwd, 16); - dump_data(100, pwd2->smb_nt_pwd, 16); -#endif - if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0) - return True; -#ifdef DEBUG_PASSWORD - DEBUG(100,("pwd compare: lm#\n")); - dump_data(100, pwd1->smb_lm_pwd, 16); - dump_data(100, pwd2->smb_lm_pwd, 16); -#endif - if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0) - return True; - } - return False; -} - -/**************************************************************************** - Reads a password. + Makes lm and nt hashed passwords. ****************************************************************************/ -void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt) +static void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) { - /* grab a password */ - char *user_pass; + pstring dos_passwd; pwd_init(pwd); - user_pass = (char*)getpass(passwd_report); - - /* - * Do not assume that an empty string is a NULL password. - * If you do this will break the session key generation for - * and account with an emtpy password. If you wish to use - * a NULL password, use the -N option to smbclient and rpcclient - * --jerry - */ -#if 0 - if (user_pass == NULL || user_pass[0] == 0) - pwd_set_nullpwd(pwd); - else if (do_encrypt) -#endif - if (do_encrypt) - pwd_make_lm_nt_16(pwd, user_pass); - else - pwd_set_cleartext(pwd, user_pass); -} - -/**************************************************************************** - Stores a cleartext password. -****************************************************************************/ - -void pwd_set_nullpwd(struct pwd_info *pwd) -{ - 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->null_pwd = True; - pwd->crypted = False; + pwd->crypted = False; } /**************************************************************************** @@ -150,29 +82,6 @@ void pwd_get_cleartext(struct pwd_info *pwd, char *clr) } -/**************************************************************************** - Stores lm and nt hashed passwords. -****************************************************************************/ - -void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) -{ - pwd_init(pwd); - - if (lm_pwd) - memcpy(pwd->smb_lm_pwd, lm_pwd, 16); - else - memset((char *)pwd->smb_lm_pwd, '\0', 16); - - if (nt_pwd) - memcpy(pwd->smb_nt_pwd, nt_pwd, 16); - else - memset((char *)pwd->smb_nt_pwd, '\0', 16); - - pwd->null_pwd = False; - pwd->cleartext = False; - pwd->crypted = False; -} - /**************************************************************************** Gets lm and nt hashed passwords. ****************************************************************************/ @@ -185,24 +94,6 @@ void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) memcpy(nt_pwd, pwd->smb_nt_pwd, 16); } -/**************************************************************************** - Makes lm and nt hashed passwords. -****************************************************************************/ - -void pwd_make_lm_nt_16(struct pwd_info *pwd, 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; -} - /**************************************************************************** Makes lm and nt OWF crypts. ****************************************************************************/ @@ -247,3 +138,13 @@ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]) if (nt_owf != NULL) memcpy(nt_owf, pwd->smb_nt_owf, 24); } + + + + + + + + + + -- cgit From 0c4c34d481be2790f0aae9f24a361f2458d1908c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 23 May 2002 14:26:04 +0000 Subject: This function is unused, and doesn't make any sense to me anyway. Wasn't this what got us some of the bugs with big-endien smbpasswd -j FOO -U ? Anyway, it deserves to die. Andrew Bartlett (This used to be commit 7201720048b31e48fb2600de8f7396088cc9b533) --- source3/libsmb/smbencrypt.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 6fa8de418a..bac64c2e50 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -324,20 +324,3 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, return True; } - -/* Calculate the NT owfs of a user's password */ -void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16]) -{ - char buf[512]; - int i; - - for (i = 0; i < MIN(pwd->uni_str_len, sizeof(buf) / 2); i++) - { - SIVAL(buf, i * 2, pwd->buffer[i]); - } - /* Calculate the MD4 hash (NT compatible) of the password */ - mdfour(nt_p16, (const unsigned char *)buf, pwd->uni_str_len * 2); - - /* clear out local copy of user's password (just being paranoid). */ - ZERO_STRUCT(buf); -} -- cgit From 9c3d5d6fd0dd9e2e62a33d0822a72d5209fe3ffb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 24 May 2002 05:14:16 +0000 Subject: Remove the password length paramater from cli_full_connection - it really didn't make any sense, and its was always just strlen(password) anyway. This fixes it to be strlen(password)+1 Andrew Bartlett (This used to be commit c205b18bd6b9b69200ff3db55f2c641631d4ab40) --- source3/libsmb/cliconnect.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f41c3b7701..7d18692236 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1030,7 +1030,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) /* Initialise client credentials for authenticated pipe access */ static void init_creds(struct ntuser_creds *creds, char* username, - char* domain, char* password, int pass_len) + char* domain, char* password) { ZERO_STRUCTP(creds); @@ -1052,7 +1052,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct in_addr *dest_ip, int port, char *service, char *service_type, char *user, char *domain, - char *password, int pass_len) + char *password) { struct ntuser_creds creds; NTSTATUS nt_status; @@ -1113,7 +1113,8 @@ again: return nt_status; } - if (!cli_session_setup(cli, user, password, pass_len, password, pass_len, + if (!cli_session_setup(cli, user, password, strlen(password)+1, + password, strlen(password)+1, domain)) { DEBUG(1,("failed session setup\n")); nt_status = cli_nt_error(cli); @@ -1125,7 +1126,7 @@ again: if (service) { if (!cli_send_tconX(cli, service, service_type, - (char*)password, pass_len)) { + (char*)password, strlen(password)+1)) { DEBUG(1,("failed tcon_X\n")); nt_status = cli_nt_error(cli); cli_shutdown(cli); @@ -1135,7 +1136,7 @@ again: } } - init_creds(&creds, user, domain, password, pass_len); + init_creds(&creds, user, domain, password); cli_init_creds(cli, &creds); *output_cli = cli; -- cgit From 20efe2fe6cbc4b5cf861a3296e29f5495637f79c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 25 May 2002 07:37:44 +0000 Subject: Clean up a few unused functions, add a bit of static etc. Importantly: The removal of the silly 'delete user script' behaviour when secuity=domain. I have left the name the same - as it still does the (previously documented, but not in smb.conf(5)) sane behaviour of deleting users on request. When we decide what to do with the 'add user' functionality, we might rename it. Andrew Bartlett (This used to be commit cdcfe3671eb7570e15649b77f708e6579055e7bc) --- source3/libsmb/cliconnect.c | 3 ++- source3/libsmb/pwd_cache.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 7d18692236..0b6436b508 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1130,8 +1130,9 @@ again: DEBUG(1,("failed tcon_X\n")); nt_status = cli_nt_error(cli); cli_shutdown(cli); - if (NT_STATUS_IS_OK(nt_status)) + if (NT_STATUS_IS_OK(nt_status)) { nt_status = NT_STATUS_UNSUCCESSFUL; + } return nt_status; } } diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 8b79788fed..fc0602507a 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -73,7 +73,7 @@ void pwd_set_cleartext(struct pwd_info *pwd, char *clr) Gets a cleartext password. ****************************************************************************/ -void pwd_get_cleartext(struct pwd_info *pwd, char *clr) +void pwd_get_cleartext(struct pwd_info *pwd, fstring clr) { if (pwd->cleartext) fstrcpy(clr, pwd->password); -- cgit From ba0b423dfa02b57d66a41ba0cf7dffad00ee19d1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 25 May 2002 08:24:24 +0000 Subject: Update some of the LM hash code to better respect the seperation between unix and DOS strings. This pushes all the 'have to uppercase, must be 14 chars' stuff behind the the interface. Andrew Bartlett (This used to be commit dec650efa8ab1466114c2e6d469320a319499ea0) --- source3/libsmb/cliconnect.c | 27 +++++++++-------- source3/libsmb/clirap.c | 11 ++----- source3/libsmb/smbencrypt.c | 73 +++++++++++++++++++++++++-------------------- 3 files changed, 57 insertions(+), 54 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 0b6436b508..8129618fda 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -63,8 +63,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, if (passlen > 0 && (cli->sec_mode & 2) && passlen != 24) { /* Encrypted mode needed, and non encrypted password supplied. */ passlen = 24; - clistr_push(cli, pword, pass, -1, STR_TERMINATE); - SMBencrypt((uchar *)pword,cli->secblob.data,(uchar *)pword); + SMBencrypt(pass,cli->secblob.data,(uchar *)pword); } else if ((cli->sec_mode & 2) && passlen == 24) { /* Encrypted mode needed, and encrypted password supplied. */ memcpy(pword, pass, passlen); @@ -241,9 +240,15 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, } -/**************************************************************************** -do a NT1 NTLM/LM encrypted session setup -****************************************************************************/ +/** + do a NT1 NTLM/LM encrypted session setup + @param cli client state to create do session setup on + @param user username + @param pass *either* cleartext password (passlen !=24) or LM response. + @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear + @param workgroup The user's domain. +*/ + static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, char *pass, int passlen, char *ntpass, int ntpasslen, @@ -261,12 +266,8 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, /* non encrypted password supplied. Ignore ntpass. */ passlen = 24; ntpasslen = 24; - clistr_push(cli, pword, - pass?pass:"", sizeof(pword), STR_TERMINATE|STR_ASCII); - clistr_push(cli, ntpword, - pass?pass:"", sizeof(ntpword), STR_TERMINATE|STR_ASCII); - SMBencrypt((uchar *)pword,cli->secblob.data,(uchar *)pword); - SMBNTencrypt((uchar *)ntpword,cli->secblob.data,(uchar *)ntpword); + SMBencrypt((uchar *)pass,cli->secblob.data,(uchar *)pword); + SMBNTencrypt((uchar *)pass,cli->secblob.data,(uchar *)ntpword); } else { memcpy(pword, pass, passlen); memcpy(ntpword, ntpass, ntpasslen); @@ -611,8 +612,8 @@ BOOL cli_session_setup(struct cli_state *cli, return cli_session_setup_plaintext(cli, user, "", workgroup); } - /* if the server doesn't support encryption then we have to use plaintext. The - second password is ignored */ + /* if the server doesn't support encryption then we have to use + plaintext. The second password is ignored */ if ((cli->sec_mode & 2) == 0) { return cli_session_setup_plaintext(cli, user, pass, workgroup); } diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index a2b6c8bb8b..3eb9586a67 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -283,8 +283,6 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char char param[16+sizeof(fstring)]; char data[532]; char *p = param; - fstring upper_case_old_pw; - fstring upper_case_new_pw; unsigned char old_pw_hash[16]; unsigned char new_pw_hash[16]; int data_len; @@ -316,9 +314,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char * Get the Lanman hash of the old password, we * use this as the key to make_oem_passwd_hash(). */ - memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw)); - clistr_push(cli, upper_case_old_pw, old_password, -1,STR_TERMINATE|STR_UPPER|STR_ASCII); - E_P16((uchar *)upper_case_old_pw, old_pw_hash); + E_deshash(old_password, old_pw_hash); clistr_push(cli, dos_new_password, new_password, -1, STR_TERMINATE|STR_ASCII); @@ -328,10 +324,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char /* * Now place the old password hash in the data. */ - memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw)); - clistr_push(cli, upper_case_new_pw, new_password, -1, STR_TERMINATE|STR_UPPER|STR_ASCII); - - E_P16((uchar *)upper_case_new_pw, new_pw_hash); + E_deshash(new_password, new_pw_hash); E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]); diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index bac64c2e50..c298616220 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -26,18 +26,14 @@ /* This implements the X/Open SMB password encryption - It takes a password, a 8 byte "crypt key" and puts 24 bytes of - encrypted password into p24 */ + It takes a password ('unix' string), a 8 byte "crypt key" + and puts 24 bytes of encrypted password into p24 */ void SMBencrypt(const uchar *passwd, const uchar *c8, uchar *p24) { - uchar p14[15], p21[21]; + uchar p21[21]; memset(p21,'\0',21); - memset(p14,'\0',14); - StrnCpy((char *)p14,(const char *)passwd,14); - - strupper((char *)p14); - E_P16(p14, p21); + E_deshash(passwd, p21); SMBOWFencrypt(p21, c8, p24); @@ -49,61 +45,74 @@ void SMBencrypt(const uchar *passwd, const uchar *c8, uchar *p24) #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 uchar *passwd, uchar *p16) +void E_md4hash(const char *passwd, uchar p16[16]) { int len; smb_ucs2_t wpwd[129]; - /* Password cannot be longer than 128 characters */ - len = strlen((const char *)passwd); - if(len > 128) - len = 128; /* 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); } -/* 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]) +/** + * 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_deshash(const char *passwd, uchar p16[16]) { - char passwd[514]; + uchar dospwd[15]; /* Password must not be > 14 chars long. */ + ZERO_STRUCT(dospwd); + ZERO_STRUCTP(p16); + + /* Password must be converted to DOS charset - null terminated. */ + push_ascii(dospwd, (const char *)passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); - memset(passwd,'\0',514); - safe_strcpy( passwd, pwd, sizeof(passwd)-1); + 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((uchar *)passwd, nt_p16); + E_md4hash(pwd, nt_p16); #ifdef DEBUG_PASSWORD DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n")); - dump_data(120, passwd, strlen(passwd)); + dump_data(120, pwd, strlen(pwd)); dump_data(100, (char *)nt_p16, 16); #endif - /* Mangle the passwords into Lanman format */ - passwd[14] = '\0'; - strupper(passwd); - - /* Calculate the SMB (lanman) hash functions of the password */ - - memset(p16, '\0', 16); - E_P16((uchar *) passwd, (uchar *)p16); + E_deshash(pwd, (uchar *)p16); #ifdef DEBUG_PASSWORD DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n")); - dump_data(120, passwd, strlen(passwd)); + dump_data(120, pwd, strlen(pwd)); dump_data(100, (char *)p16, 16); #endif - /* clear out local copy of user's password (just being paranoid). */ - memset(passwd, '\0', sizeof(passwd)); } /* Does both the NTLMv2 owfs of a user's password */ -- cgit From 069e6fb9eb4a0bf6720cbbf493d0cb36baac9580 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 26 May 2002 14:59:57 +0000 Subject: Add support for NTLMv2 (tested!) with NTLMSSP. The problem was the NTLMv2 uses extra data in order to make reply/lookup more difficult. That extra data includes the hostname, and the domain. This matches Win2k (sort of) by sending this information. Win2k connects with LMCompatibilityLevel=5 without a problem. We can change the negotiation bits if we want, this should allow us to make NTLMv2 the default for other clients as well. Some of the extra #defines were found in the squid source. Andrew Bartlett (This used to be commit 17a5f67b3d1935baf6197ae967624eb847b66ac8) --- source3/libsmb/clispnego.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index a4fcfa5d9a..469b946088 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -549,7 +549,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, format specifiers are: - U = unicode string (input is unix string) + U = unicode string (output is unix string) B = data blob b = data blob in header d = word (4 bytes) @@ -620,3 +620,44 @@ BOOL msrpc_parse(DATA_BLOB *blob, return True; } + +/** + * Print out the NTLMSSP flags for debugging + */ + +void debug_ntlmssp_flags(uint32 neg_flags) +{ + if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) + DEBUG(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_OEM) + DEBUG(4, (" NTLMSSP_NEGOTIATE_OEM\n")); + if (neg_flags & NTLMSSP_REQUEST_TARGET) + DEBUG(4, (" NTLMSSP_REQUEST_TARGET\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) + DEBUG(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) + DEBUG(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) + DEBUG(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) + DEBUG(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) + DEBUG(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) + DEBUG(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) + DEBUG(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) + DEBUG(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) + DEBUG(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) + DEBUG(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); + if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) + DEBUG(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_128) + DEBUG(4, (" NTLMSSP_NEGOTIATE_128\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) + DEBUG(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); +} + -- cgit From f00e292be91f76c57637d1e1b2d075ec0e765691 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 28 May 2002 08:39:12 +0000 Subject: Hmm - you can do NT_STATUS_IS_OK on a WERROR and not get a compile warning/error. (This used to be commit 8d6270cadf7f99ee8ee441ee6c3e58eca623d519) --- source3/libsmb/cli_spoolss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 5e33e00c68..48094f8179 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -606,7 +606,7 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (NT_STATUS_IS_OK(result)) { + if (W_ERROR_IS_OK(result)) { switch (level) { case 0: decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0); -- cgit From 742ed34e470cf1e9c406b5a06a3274146d26b2d5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 28 May 2002 08:43:22 +0000 Subject: Added netshareenum cli command - the rpc structures here are really bizzare so muchos dodgy code is required to copy the results out of the parse buffer into the client's talloc context. (This used to be commit 496d3cf02c15ece7e13fa023deea740ee00486a8) --- source3/libsmb/cli_srvsvc.c | 120 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index b5b4478684..302b45960e 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -68,3 +68,123 @@ NTSTATUS cli_srvsvc_net_srv_get_info(struct cli_state *cli, return result; } + +WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 info_level, SRV_SHARE_INFO_CTR *ctr, + int preferred_len, ENUM_HND *hnd) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_SHARE_ENUM q; + SRV_R_NET_SHARE_ENUM r; + WERROR result = W_ERROR(ERRgeneral); + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_srv_q_net_share_enum( + &q, cli->srv_name_slash, info_level, preferred_len, hnd); + + /* Marshall data and send request */ + + if (!srv_io_q_net_share_enum("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NETSHAREENUM_ALL, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!srv_io_r_net_share_enum("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(result)) + goto done; + + /* Oh yuck yuck yuck - we have to copy all the info out of the + SRV_SHARE_INFO_CTR in the SRV_R_NET_SHARE_ENUM as when we do a + prs_mem_free() it will all be invalidated. The various share + info structures suck badly too. This really is gross. */ + + ZERO_STRUCTP(ctr); + + ctr->info_level = info_level; + ctr->num_entries = r.ctr.num_entries; + + switch(info_level) { + case 1: + ctr->share.info1 = (SRV_SHARE_INFO_1 *)talloc( + mem_ctx, sizeof(SRV_SHARE_INFO_1) * ctr->num_entries); + + memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1)); + + for (i = 0; i < ctr->num_entries; i++) { + SRV_SHARE_INFO_1 *info1 = &ctr->share.info1[i]; + char *s; + + /* Copy pointer crap */ + + memcpy(&info1->info_1, &r.ctr.share.info1[i].info_1, + sizeof(SH_INFO_1)); + + /* Duplicate strings */ + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_netname); + if (s) + init_unistr2(&info1->info_1_str.uni_netname, s, strlen(s) + 1); + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_remark); + if (s) + init_unistr2(&info1->info_1_str.uni_remark, s, strlen(s) + 1); + + } + + break; + case 2: + ctr->share.info2 = (SRV_SHARE_INFO_2 *)talloc( + mem_ctx, sizeof(SRV_SHARE_INFO_2) * ctr->num_entries); + + memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2)); + + for (i = 0; i < ctr->num_entries; i++) { + SRV_SHARE_INFO_2 *info2 = &ctr->share.info2[i]; + char *s; + + /* Copy pointer crap */ + + memcpy(&info2->info_2, &r.ctr.share.info2[i].info_2, + sizeof(SH_INFO_2)); + + /* Duplicate strings */ + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_netname); + if (s) + init_unistr2(&info2->info_2_str.uni_netname, s, strlen(s) + 1); + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_remark); + if (s) + init_unistr2(&info2->info_2_str.uni_remark, s, strlen(s) + 1); + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_path); + if (s) + init_unistr2(&info2->info_2_str.uni_path, s, strlen(s) + 1); + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_passwd); + if (s) + init_unistr2(&info2->info_2_str.uni_passwd, s, strlen(s) + 1); + } + break; + } + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 43b35364ffda5c779452fb41c015b280fefc6ab6 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 29 May 2002 00:49:26 +0000 Subject: Cleaned up srvsvc constants a bit. (This used to be commit ca61f68d5ca8791bea34732bd358cfb63273fc5c) --- source3/libsmb/cli_srvsvc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 302b45960e..f3d012434e 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -95,7 +95,7 @@ WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Marshall data and send request */ if (!srv_io_q_net_share_enum("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NETSHAREENUM_ALL, &qbuf, &rbuf)) + !rpc_api_pipe_req(cli, SRV_NET_SHARE_ENUM_ALL, &qbuf, &rbuf)) goto done; /* Unmarshall response */ -- cgit From 568deecbf0bcda46fd9c927ad10b76d748b8c64d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 29 May 2002 01:43:44 +0000 Subject: Added netremotetod to try and figure out which srvsvc commands are denied when using restrictanonymous. (This used to be commit 0c65978ed07903af808da5f32cc29531aef23225) --- source3/libsmb/cli_srvsvc.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index f3d012434e..9e2f5a3686 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -188,3 +188,48 @@ WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *server, TIME_OF_DAY_INFO *tod) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_REMOTE_TOD q; + SRV_R_NET_REMOTE_TOD r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_srv_q_net_remote_tod(&q, cli->srv_name_slash); + + /* Marshall data and send request */ + + if (!srv_io_q_net_remote_tod("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NET_REMOTE_TOD, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + r.tod = tod; + + if (!srv_io_r_net_remote_tod("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(result)) + goto done; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 0e3260de6fdaa93ce0dddd98b1413662be972ce3 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 30 May 2002 07:12:32 +0000 Subject: Added netfileenum (sorry - no output though (-:) command. (This used to be commit 099b750b4ed8f04a1fd8a018508d412691e37df6) --- source3/libsmb/cli_srvsvc.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 9e2f5a3686..bc2058fdbd 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -233,3 +233,48 @@ WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 file_level, SRV_FILE_INFO_CTR *ctr, + int preferred_len, ENUM_HND *hnd) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_FILE_ENUM q; + SRV_R_NET_FILE_ENUM r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_srv_q_net_file_enum(&q, cli->srv_name_slash, NULL, file_level, + ctr, preferred_len, hnd); + + /* Marshall data and send request */ + + if (!srv_io_q_net_file_enum("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NET_FILE_ENUM, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!srv_io_r_net_file_enum("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(result)) + goto done; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From e422b271da0c07f5c5cfd41df01bb2910d484abc Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 31 May 2002 17:02:09 +0000 Subject: Update netfileenum on both client and server sides to do an arbitrary number of files. This was done to better enable net rpc file. Perhaps we can start giving back real info this way, too. (This used to be commit b3fea72ee9abd2441a49c35442c54819e4ba16ba) --- source3/libsmb/cli_srvsvc.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index bc2058fdbd..8e1c6e0c9d 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -4,6 +4,7 @@ Copyright (C) Andrew Tridgell 1994-2000 Copyright (C) Luke Kenneth Casson Leighton 1996-2000 Copyright (C) Tim Potter 2001 + Copyright (C) Jim McDonough 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 @@ -242,6 +243,7 @@ WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, SRV_Q_NET_FILE_ENUM q; SRV_R_NET_FILE_ENUM r; WERROR result = W_ERROR(ERRgeneral); + int i; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -272,6 +274,46 @@ WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (!W_ERROR_IS_OK(result)) goto done; + /* copy the data over to the ctr */ + + ZERO_STRUCTP(ctr); + + ctr->switch_value = file_level; + + ctr->num_entries = ctr->num_entries2 = r.ctr.num_entries; + + switch(file_level) { + case 3: + ctr->file.info3 = (SRV_FILE_INFO_3 *)talloc( + mem_ctx, sizeof(SRV_FILE_INFO_3) * ctr->num_entries); + + memset(ctr->file.info3, 0, + sizeof(SRV_FILE_INFO_3) * ctr->num_entries); + + for (i = 0; i < r.ctr.num_entries; i++) { + SRV_FILE_INFO_3 *info3 = &ctr->file.info3[i]; + char *s; + + /* Copy pointer crap */ + + memcpy(&info3->info_3, &r.ctr.file.info3[i].info_3, + sizeof(FILE_INFO_3)); + + /* Duplicate strings */ + + s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_path_name); + if (s) + init_unistr2(&info3->info_3_str.uni_path_name, s, strlen(s) + 1); + + s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_user_name); + if (s) + init_unistr2(&info3->info_3_str.uni_user_name, s, strlen(s) + 1); + + } + + break; + } + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); -- cgit From 0f7e6fd0ec1dbe4a5d75a7df2f5ac32e95fd4d9a Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 31 May 2002 21:09:58 +0000 Subject: Add netshareadd and netsharedel client side rpc (This used to be commit f37d85babf1061bb2b5ffdf96c72427f8ad5e832) --- source3/libsmb/cli_srvsvc.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 8e1c6e0c9d..6910ba0c5b 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -190,6 +190,87 @@ WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +WERROR cli_srvsvc_net_share_del(struct cli_state *cli, TALLOC_CTX *mem_ctx, + const char *sharename) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_SHARE_DEL q; + SRV_R_NET_SHARE_DEL r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_srv_q_net_share_del(&q, cli->srv_name_slash, sharename); + + /* Marshall data and send request */ + + if (!srv_io_q_net_share_del("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NET_SHARE_DEL, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!srv_io_r_net_share_del("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +WERROR cli_srvsvc_net_share_add(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *netname, uint32 type, char *remark, + uint32 perms, uint32 max_uses, uint32 num_uses, + char *path, char *passwd) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_SHARE_ADD q; + SRV_R_NET_SHARE_ADD r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + init_srv_q_net_share_add(&q,cli->srv_name_slash, netname, type, remark, + perms, max_uses, num_uses, path, passwd); + + /* Marshall data and send request */ + + if (!srv_io_q_net_share_add("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NET_SHARE_ADD, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!srv_io_r_net_share_add("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx, char *server, TIME_OF_DAY_INFO *tod) { -- cgit From 654273856863d861c8be7b46c39e68a81ea3807a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 1 Jun 2002 00:10:08 +0000 Subject: More cleanup work preparing for SMB signing. Jeremy. (This used to be commit 3c05f7c06fc8c45307ea75128b160a5945fc5197) --- source3/libsmb/cli_lsarpc.c | 2 +- source3/libsmb/cliconnect.c | 192 ++++++++++++++++++++++++-------------------- 2 files changed, 105 insertions(+), 89 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 9d07eb1d1e..7dfee46fae 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -1122,7 +1122,7 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); goto done; } - if (!(cli.sec_mode & 1)) { + if (!(cli.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { DEBUG(0,("fetch_domain_sid: machine %s isn't in user level security mode\n", remote_machine)); goto done; diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8129618fda..86daafc50b 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -24,27 +24,25 @@ 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_LANMAN2,"LM1.2X002"}, - {PROTOCOL_LANMAN2,"DOS LANMAN2.1"}, - {PROTOCOL_LANMAN2,"Samba"}, - {PROTOCOL_NT1,"NT LANMAN 1.0"}, - {PROTOCOL_NT1,"NT LM 0.12"}, - {-1,NULL} - }; - + 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_LANMAN2,"LM1.2X002"}, + {PROTOCOL_LANMAN2,"DOS LANMAN2.1"}, + {PROTOCOL_LANMAN2,"Samba"}, + {PROTOCOL_NT1,"NT LANMAN 1.0"}, + {PROTOCOL_NT1,"NT LM 0.12"}, + {-1,NULL} +}; /**************************************************************************** -do an old lanman2 style session setup + Do an old lanman2 style session setup. ****************************************************************************/ + static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, char *pass, int passlen, const char *workgroup) { @@ -56,15 +54,15 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, } /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & 1)) { + if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { passlen = 0; } - if (passlen > 0 && (cli->sec_mode & 2) && passlen != 24) { + if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) { /* Encrypted mode needed, and non encrypted password supplied. */ passlen = 24; SMBencrypt(pass,cli->secblob.data,(uchar *)pword); - } else if ((cli->sec_mode & 2) && passlen == 24) { + } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) { /* Encrypted mode needed, and encrypted password supplied. */ memcpy(pword, pass, passlen); } else if (passlen > 0) { @@ -111,10 +109,10 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, return True; } - /**************************************************************************** -work out suitable capabilities to offer the server + Work out suitable capabilities to offer the server. ****************************************************************************/ + static uint32 cli_session_setup_capabilities(struct cli_state *cli) { uint32 capabilities = CAP_NT_SMBS; @@ -134,15 +132,18 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli) return capabilities; } - /**************************************************************************** -do a NT1 guest session setup + Do a NT1 guest session setup. ****************************************************************************/ + static BOOL cli_session_setup_guest(struct cli_state *cli) { char *p; uint32 capabilities = cli_session_setup_capabilities(cli); + /* Guest cannot use SMB signing. */ + cli->sign_info.use_smb_signing = False; + set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -184,10 +185,10 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) return True; } - /**************************************************************************** -do a NT1 plaintext session setup + Do a NT1 plaintext session setup. ****************************************************************************/ + static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, char *pass, char *workgroup) { @@ -320,10 +321,10 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, return True; } - /**************************************************************************** -send a extended security session setup blob, returning a reply blob + Send a extended security session setup blob, returning a reply blob. ****************************************************************************/ + static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) { uint32 capabilities = cli_session_setup_capabilities(cli); @@ -387,8 +388,9 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) #ifdef HAVE_KRB5 /**************************************************************************** -do a spnego/kerberos encrypted session setup + Do a spnego/kerberos encrypted session setup. ****************************************************************************/ + static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, char *workgroup) { DATA_BLOB blob2, negTokenTarg; @@ -416,8 +418,9 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, c #endif /**************************************************************************** -do a spnego/NTLMSSP encrypted session setup + Do a spnego/NTLMSSP encrypted session setup. ****************************************************************************/ + static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, char *pass, char *workgroup) { @@ -506,10 +509,10 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, return !cli_is_error(cli); } - /**************************************************************************** -do a spnego encrypted session setup + Do a spnego encrypted session setup. ****************************************************************************/ + static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, char *pass, char *workgroup) { @@ -563,12 +566,12 @@ ntlmssp: return cli_session_setup_ntlmssp(cli, user, pass, workgroup); } - /**************************************************************************** Send a session setup. The username and workgroup is in UNIX character format and must be converted to DOS codepage format before sending. If the password is in plaintext, the same should be done. ****************************************************************************/ + BOOL cli_session_setup(struct cli_state *cli, char *user, char *pass, int passlen, @@ -608,13 +611,13 @@ BOOL cli_session_setup(struct cli_state *cli, /* if the server is share level then send a plaintext null password at this point. The password is sent in the tree connect */ - if ((cli->sec_mode & 1) == 0) { + if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) { return cli_session_setup_plaintext(cli, user, "", workgroup); } /* if the server doesn't support encryption then we have to use plaintext. The second password is ignored */ - if ((cli->sec_mode & 2) == 0) { + if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) { return cli_session_setup_plaintext(cli, user, pass, workgroup); } @@ -650,8 +653,9 @@ BOOL cli_ulogoff(struct cli_state *cli) } /**************************************************************************** -send a tconX + Send a tconX. ****************************************************************************/ + BOOL cli_send_tconX(struct cli_state *cli, const char *share, const char *dev, const char *pass, int passlen) { @@ -663,12 +667,12 @@ BOOL cli_send_tconX(struct cli_state *cli, fstrcpy(cli->share, share); /* in user level security don't send a password now */ - if (cli->sec_mode & 1) { + if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) { passlen = 1; pass = ""; } - if ((cli->sec_mode & 2) && *pass && passlen != 24) { + if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && *pass && passlen != 24) { /* * Non-encrypted passwords - convert to DOS codepage before encryption. */ @@ -676,7 +680,7 @@ BOOL cli_send_tconX(struct cli_state *cli, clistr_push(cli, dos_pword, pass, -1, STR_TERMINATE); SMBencrypt((uchar *)dos_pword,cli->secblob.data,(uchar *)pword); } else { - if((cli->sec_mode & 3) == 0) { + if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) { /* * Non-encrypted passwords - convert to DOS codepage before using. */ @@ -733,10 +737,10 @@ BOOL cli_send_tconX(struct cli_state *cli, return True; } - /**************************************************************************** -send a tree disconnect + Send a tree disconnect. ****************************************************************************/ + BOOL cli_tdis(struct cli_state *cli) { memset(cli->outbuf,'\0',smb_size); @@ -752,10 +756,10 @@ BOOL cli_tdis(struct cli_state *cli) return !cli_is_error(cli); } - /**************************************************************************** -send a negprot command + Send a negprot command. ****************************************************************************/ + void cli_negprot_send(struct cli_state *cli) { char *p; @@ -787,10 +791,10 @@ void cli_negprot_send(struct cli_state *cli) cli_send_smb(cli); } - /**************************************************************************** -send a negprot command + Send a negprot command. ****************************************************************************/ + BOOL cli_negprot(struct cli_state *cli) { char *p; @@ -860,6 +864,14 @@ BOOL cli_negprot(struct cli_state *cli) smb_buf(cli->inbuf)+8, sizeof(cli->server_domain), smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN); } + + /* A way to attempt to force SMB signing */ + if (getenv("CLI_FORCE_SMB_SIGNING")) + cli->sign_info.use_smb_signing = True; + + if (cli->sign_info.use_smb_signing && !(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) + cli->sign_info.use_smb_signing = False; + } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->use_spnego = False; cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); @@ -872,11 +884,13 @@ BOOL cli_negprot(struct cli_state *cli) cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf)); + cli->sign_info.use_smb_signing = False; } else { /* the old core protocol */ cli->use_spnego = False; cli->sec_mode = 0; cli->serverzone = TimeDiff(time(NULL)); + cli->sign_info.use_smb_signing = False; } cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); @@ -889,10 +903,10 @@ BOOL cli_negprot(struct cli_state *cli) return True; } - /**************************************************************************** - send a session request. see rfc1002.txt 4.3 and 4.3.2 + Send a session request. See rfc1002.txt 4.3 and 4.3.2. ****************************************************************************/ + BOOL cli_session_request(struct cli_state *cli, struct nmb_name *calling, struct nmb_name *called) { @@ -975,8 +989,9 @@ BOOL cli_session_request(struct cli_state *cli, } /**************************************************************************** -open the client sockets + Open the client sockets. ****************************************************************************/ + BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) { extern pstring user_socket_options; @@ -1028,7 +1043,9 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) return True; } -/* Initialise client credentials for authenticated pipe access */ +/**************************************************************************** + Initialise client credentials for authenticated pipe access. +****************************************************************************/ static void init_creds(struct ntuser_creds *creds, char* username, char* domain, char* password) @@ -1046,8 +1063,9 @@ static void init_creds(struct ntuser_creds *creds, char* username, } /**************************************************************************** -establishes a connection right up to doing tconX, password specified. + Establishes a connection right up to doing tconX, password specified. ****************************************************************************/ + NTSTATUS cli_full_connection(struct cli_state **output_cli, const char *my_name, const char *dest_host, struct in_addr *dest_ip, int port, @@ -1152,55 +1170,53 @@ again: BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, struct in_addr *pdest_ip) { - struct nmb_name calling, called; + struct nmb_name calling, called; - make_nmb_name(&calling, srchost, 0x0); + make_nmb_name(&calling, srchost, 0x0); - /* - * If the called name is an IP address - * then use *SMBSERVER immediately. - */ + /* + * If the called name is an IP address + * then use *SMBSERVER immediately. + */ - if(is_ipaddress(desthost)) - make_nmb_name(&called, "*SMBSERVER", 0x20); - else - make_nmb_name(&called, desthost, 0x20); + if(is_ipaddress(desthost)) + make_nmb_name(&called, "*SMBSERVER", 0x20); + else + make_nmb_name(&called, desthost, 0x20); - if (!cli_session_request(cli, &calling, &called)) { - struct nmb_name smbservername; + if (!cli_session_request(cli, &calling, &called)) { + struct nmb_name smbservername; - make_nmb_name(&smbservername , "*SMBSERVER", 0x20); + make_nmb_name(&smbservername , "*SMBSERVER", 0x20); - /* - * If the name wasn't *SMBSERVER then - * try with *SMBSERVER if the first name fails. - */ + /* + * If the name wasn't *SMBSERVER then + * try with *SMBSERVER if the first name fails. + */ - if (nmb_name_equal(&called, &smbservername)) { + if (nmb_name_equal(&called, &smbservername)) { - /* - * The name used was *SMBSERVER, don't bother with another name. - */ + /* + * The name used was *SMBSERVER, don't bother with another name. + */ - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ with error %s.\n", desthost, cli_errstr(cli) )); - cli_shutdown(cli); - return False; - } + cli_shutdown(cli); + return False; + } - cli_shutdown(cli); + cli_shutdown(cli); - if (!cli_initialise(cli) || - !cli_connect(cli, desthost, pdest_ip) || - !cli_session_request(cli, &calling, &smbservername)) { - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ + if (!cli_initialise(cli) || + !cli_connect(cli, desthost, pdest_ip) || + !cli_session_request(cli, &calling, &smbservername)) { + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); - cli_shutdown(cli); - return False; - } - } + cli_shutdown(cli); + return False; + } + } - return True; + return True; } - - -- cgit From 4caf48a7005407e16fca7ea4414c4a00bddb7c85 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Sat, 1 Jun 2002 01:02:04 +0000 Subject: Add rpc for file close, expand file enum to take username (This used to be commit 4b18a94590a25882f06f88c3c7dd1a08bf990044) --- source3/libsmb/cli_srvsvc.c | 48 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 6910ba0c5b..91fd1e00c7 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -317,8 +317,9 @@ WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx, } WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 file_level, SRV_FILE_INFO_CTR *ctr, - int preferred_len, ENUM_HND *hnd) + uint32 file_level, char *user_name, + SRV_FILE_INFO_CTR *ctr, int preferred_len, + ENUM_HND *hnd) { prs_struct qbuf, rbuf; SRV_Q_NET_FILE_ENUM q; @@ -336,8 +337,8 @@ WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ - init_srv_q_net_file_enum(&q, cli->srv_name_slash, NULL, file_level, - ctr, preferred_len, hnd); + init_srv_q_net_file_enum(&q, cli->srv_name_slash, NULL, user_name, + file_level, ctr, preferred_len, hnd); /* Marshall data and send request */ @@ -401,3 +402,42 @@ WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +WERROR cli_srvsvc_net_file_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 file_id) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_FILE_CLOSE q; + SRV_R_NET_FILE_CLOSE r; + WERROR result = W_ERROR(ERRgeneral); + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_srv_q_net_file_close(&q, cli->srv_name_slash, file_id); + + /* Marshall data and send request */ + + if (!srv_io_q_net_file_close("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NET_FILE_CLOSE, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!srv_io_r_net_file_close("", &r, &rbuf, 0)) + goto done; + + result = r.status; + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + return result; +} -- cgit From ef5e092bb9a97300b1d6a754f918facd71c77fdb Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 3 Jun 2002 02:20:56 +0000 Subject: Removed unused variable. (This used to be commit a8b2e76c5b90d3dcd00f26462614f56936c13110) --- source3/libsmb/cli_srvsvc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 91fd1e00c7..2dc12d726c 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -410,7 +410,6 @@ WERROR cli_srvsvc_net_file_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, SRV_Q_NET_FILE_CLOSE q; SRV_R_NET_FILE_CLOSE r; WERROR result = W_ERROR(ERRgeneral); - int i; ZERO_STRUCT(q); ZERO_STRUCT(r); -- cgit From b433a90f021c86f39fbd1efb3d0de3ddbeb25afc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 3 Jun 2002 02:23:05 +0000 Subject: Added cli_samr_get_dom_pwinfo() function. Some reformatting. (This used to be commit d6dd7c7b14a4e3be4d7d435b6ac6bb8189070ff7) --- source3/libsmb/cli_samr.c | 120 ++++++++++++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 46 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 9a332aa99e..dfc4ccf706 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -47,15 +47,13 @@ NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_connect(&q, cli->desthost, access_mask); if (!samr_io_q_connect("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_connect("", &r, &rbuf, 0)) { + if (!samr_io_r_connect("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -96,15 +94,13 @@ NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_close_hnd(&q, connect_pol); if (!samr_io_q_close_hnd("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_close_hnd("", &r, &rbuf, 0)) { + if (!samr_io_r_close_hnd("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -146,15 +142,13 @@ NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid); if (!samr_io_q_open_domain("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_open_domain("", &r, &rbuf, 0)) { + if (!samr_io_r_open_domain("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -196,15 +190,13 @@ NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_open_user(&q, domain_pol, access_mask, user_rid); if (!samr_io_q_open_user("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_open_user("", &r, &rbuf, 0)) { + if (!samr_io_r_open_user("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -246,15 +238,13 @@ NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_open_group(&q, domain_pol, access_mask, group_rid); if (!samr_io_q_open_group("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_open_group("", &r, &rbuf, 0)) { + if (!samr_io_r_open_group("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -296,15 +286,13 @@ NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_query_userinfo(&q, user_pol, switch_value); if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) { + if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -342,17 +330,15 @@ NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_query_groupinfo(&q, group_pol, info_level); if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ r.ctr = ctr; - if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0)) { + if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -389,15 +375,13 @@ NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_query_usergroups(&q, user_pol); if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_query_usergroups("", &r, &rbuf, 0)) { + if (!samr_io_r_query_usergroups("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -438,15 +422,13 @@ NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_query_useraliases(&q, user_pol, num_sids, &ptr, sid); if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_query_useraliases("", &r, &rbuf, 0)) { + if (!samr_io_r_query_useraliases("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -486,15 +468,13 @@ NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_query_groupmem(&q, group_pol); if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_query_groupmem("", &r, &rbuf, 0)) { + if (!samr_io_r_query_groupmem("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -537,24 +517,21 @@ NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_enum_dom_groups(&q, pol, *start_idx, size); if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0)) { + if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ result = r.status; if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) { + NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) goto done; - } *num_dom_groups = r.num_entries2; @@ -1264,3 +1241,54 @@ NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +/* Get domain password info */ + +NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint16 *unk_0, uint16 *unk_1, uint16 *unk_2) +{ + prs_struct qbuf, rbuf; + SAMR_Q_GET_DOM_PWINFO q; + SAMR_R_GET_DOM_PWINFO r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_get_dom_pwinfo(&q, cli->desthost); + + if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + if (NT_STATUS_IS_OK(result)) { + if (unk_0) + *unk_0 = r.unk_0; + if (unk_1) + *unk_1 = r.unk_1; + if (unk_2) + *unk_2 = r.unk_2; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From ce62a480e51afc584d6a27cae164371fc742d539 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 3 Jun 2002 04:28:53 +0000 Subject: Removed unused function. (This used to be commit f7e75952306296b11a859f425ff5ec7082239dc2) --- source3/libsmb/namequery.c | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 85f33aeda4..a97270b7d4 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1008,52 +1008,6 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) return False; } - -/******************************************************** - resolve a name of format \\server_name or \\ipaddress - into a name. also, cut the \\ from the front for us. -*********************************************************/ - -BOOL resolve_srv_name(const char* srv_name, fstring dest_host, - struct in_addr *ip) -{ - BOOL ret; - const char *sv_name = srv_name; - - DEBUG(10,("resolve_srv_name: %s\n", srv_name)); - - if (srv_name == NULL || strequal("\\\\.", srv_name)) - { - extern pstring global_myname; - fstrcpy(dest_host, global_myname); - ip = interpret_addr2("127.0.0.1"); - return True; - } - - if (strnequal("\\\\", srv_name, 2)) - { - sv_name = &srv_name[2]; - } - - fstrcpy(dest_host, sv_name); - /* treat the '*' name specially - it is a magic name for the PDC */ - if (strcmp(dest_host,"*") == 0) { - extern pstring global_myname; - ret = resolve_name(lp_workgroup(), ip, 0x1B); - lookup_dc_name(global_myname, lp_workgroup(), ip, dest_host); - } else { - ret = resolve_name(dest_host, ip, 0x20); - } - - if (is_ipaddress(dest_host)) - { - fstrcpy(dest_host, "*SMBSERVER"); - } - - return ret; -} - - /******************************************************** Find the IP address of the master browser or DMB for a workgroup. *********************************************************/ -- cgit From d5154cb241e38106994a76806f7968619b5ec270 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 7 Jun 2002 12:41:04 +0000 Subject: A couple of updates for the SmbEncrypt code, and some of its users. (const, takes unix string as arg) Also update cli_full_connection to take NULL pointers as 'undefined' correctly, and therefore do its own lookup etc. This what was intended, but previously you needed to supply a 0.0.0.0 IP address. Andrew Bartlett (This used to be commit 8fb1a9c6ba07dbf04a6aa1e30fa7bbd4c676ed28) --- source3/libsmb/cliconnect.c | 44 +++++++++++++++++++++++++++++++------------- source3/libsmb/smbencrypt.c | 2 +- 2 files changed, 32 insertions(+), 14 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 86daafc50b..ebd25627c1 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -659,7 +659,7 @@ BOOL cli_ulogoff(struct cli_state *cli) BOOL cli_send_tconX(struct cli_state *cli, const char *share, const char *dev, const char *pass, int passlen) { - fstring fullshare, pword, dos_pword; + fstring fullshare, pword; char *p; memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); @@ -677,8 +677,7 @@ BOOL cli_send_tconX(struct cli_state *cli, * Non-encrypted passwords - convert to DOS codepage before encryption. */ passlen = 24; - clistr_push(cli, dos_pword, pass, -1, STR_TERMINATE); - SMBencrypt((uchar *)dos_pword,cli->secblob.data,(uchar *)pword); + SMBencrypt(pass,cli->secblob.data,(uchar *)pword); } else { if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) { /* @@ -1062,9 +1061,18 @@ static void init_creds(struct ntuser_creds *creds, char* username, } } -/**************************************************************************** - Establishes a connection right up to doing tconX, password specified. -****************************************************************************/ +/** + establishes a connection right up to doing tconX, password specified. + @param output_cli A fully initialised cli structure, non-null only on success + @param dest_host The netbios name of the remote host + @param dest_ip (optional) The the destination IP, NULL for name based lookup + @param port (optional) The destination port (0 for default) + @param service The share to make the connection to. Should be 'unqualified' in any way. + @param service_type The 'type' of serivice. + @param user Username, unix string + @param domain User's domain + @param password User's password, unencrypted unix string. +*/ NTSTATUS cli_full_connection(struct cli_state **output_cli, const char *my_name, const char *dest_host, @@ -1079,17 +1087,21 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct nmb_name called; struct cli_state *cli; struct in_addr ip; - - if (!output_cli) + extern pstring global_myname; + + if (!output_cli) { DEBUG(0, ("output_cli is NULL!?!")); + SMB_ASSERT("output_cli for cli_full_connection was NULL.\n"); + } *output_cli = NULL; + + if (!my_name) + my_name = global_myname; make_nmb_name(&calling, my_name, 0x0); make_nmb_name(&called , dest_host, 0x20); -again: - if (!(cli = cli_initialise(NULL))) return NT_STATUS_NO_MEMORY; @@ -1098,13 +1110,19 @@ again: return NT_STATUS_UNSUCCESSFUL; } - ip = *dest_ip; - + if (dest_ip) { + ip = *dest_ip; + } else { + ZERO_STRUCT(ip); + } + +again: + DEBUG(3,("Connecting to host=%s share=%s\n", dest_host, service)); if (!cli_connect(cli, dest_host, &ip)) { DEBUG(1,("cli_full_connection: failed to connect to %s (%s)\n", - nmb_namestr(&called), inet_ntoa(*dest_ip))); + nmb_namestr(&called), inet_ntoa(ip))); cli_shutdown(cli); return NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index c298616220..fa1eaedb5a 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -28,7 +28,7 @@ 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 uchar *passwd, const uchar *c8, uchar *p24) +void SMBencrypt(const char *passwd, const uchar *c8, uchar *p24) { uchar p21[21]; -- cgit From 3838eabc0e9ba2ef91d90a406767814ab61bc18a Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 12 Jun 2002 01:33:30 +0000 Subject: Removed eff_name field from cli_struct as it wasn't being used anywhere. (This used to be commit aff65bf6c9f339ae1d3122d12114005c017b9b5d) --- source3/libsmb/clirap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 3eb9586a67..2064e14954 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -117,7 +117,8 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) if (cli->rap_error == 0) { DEBUG(4,("NetWkstaUserLogon success\n")); cli->privileges = SVAL(p, 24); - fstrcpy(cli->eff_name,p+2); + /* The cli->eff_name field used to be set here + but it wasn't used anywhere else. */ } else { DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->rap_error)); } -- cgit From caa4262db6115a6880af9618b7fe8130eecd4b98 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Jun 2002 22:38:43 +0000 Subject: More of SMB signing for client - not yet finished (should be harmless). Jeremy. (This used to be commit c1b20db4bb4bb1ba485466f50b9795470027327c) --- source3/libsmb/clientgen.c | 23 ++++++++++++++--------- source3/libsmb/smbencrypt.c | 27 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index dee86b2b05..5f42148078 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -107,7 +107,7 @@ BOOL cli_receive_smb(struct cli_state *cli) } /**************************************************************************** - send an smb to a fd. + Send an smb to a fd. ****************************************************************************/ BOOL cli_send_smb(struct cli_state *cli) @@ -117,31 +117,34 @@ BOOL cli_send_smb(struct cli_state *cli) ssize_t ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ - if (cli->fd == -1) return False; + if (cli->fd == -1) + return False; + + if (SVAL(cli->outbuf,smb_flg2) & FLAGS2_SMB_SECUIRTY_SIGNITURES) + cli_caclulate_sign_mac(cli); len = smb_len(cli->outbuf) + 4; while (nwritten < len) { ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); if (ret <= 0) { - close(cli->fd); - cli->fd = -1; - DEBUG(0,("Error writing %d bytes to client. %d\n", - (int)len,(int)ret)); + close(cli->fd); + cli->fd = -1; + DEBUG(0,("Error writing %d bytes to client. %d\n", (int)len,(int)ret)); return False; } nwritten += ret; } - return True; } /**************************************************************************** -setup basics in a outgoing packet + Setup basics in a outgoing packet. ****************************************************************************/ + void cli_setup_packet(struct cli_state *cli) { - cli->rap_error = 0; + cli->rap_error = 0; SSVAL(cli->outbuf,smb_pid,cli->pid); SSVAL(cli->outbuf,smb_uid,cli->vuid); SSVAL(cli->outbuf,smb_mid,cli->mid); @@ -158,6 +161,8 @@ void cli_setup_packet(struct cli_state *cli) if (cli->use_spnego) { flags2 |= FLAGS2_EXTENDED_SECURITY; } + if (cli->sign_info.use_smb_signing) + flags2 |= FLAGS2_SMB_SECUIRTY_SIGNITURES; SSVAL(cli->outbuf,smb_flg2, flags2); } } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index fa1eaedb5a..de469c0293 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -331,5 +331,32 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, #endif return True; +} + +/*********************************************************** + SMB signing - calculate a MAC to send. +************************************************************/ +void cli_caclulate_sign_mac(struct cli_state *cli) +{ + unsigned char calc_md5_mac[16]; + struct MD5Context md5_ctx; + + /* + * Firstly put the sequence number into the first 4 bytes. + * and zero out the next 4 bytes. + */ + SIVAL(cli->outbuf, smb_ss_field, cli->sign_info.send_seq_num); + SIVAL(cli->outbuf, smb_ss_field + 4, 0); + + /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, cli->sign_info.mac_key, cli->sign_info.mac_key_len); + MD5Update(&md5_ctx, cli->outbuf + 4, smb_len(cli->outbuf)); + MD5Final(calc_md5_mac, &md5_ctx); + + memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); + cli->sign_info.send_seq_num++; + cli->sign_info.reply_seq_num = cli->sign_info.send_seq_num; + cli->sign_info.send_seq_num++; } -- cgit From 998fe278808728231b9c2d2869d5b1fb7ee19293 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Jun 2002 23:01:11 +0000 Subject: Ok, now I can try my first client test... Jeremy. (This used to be commit 9d461933766f26ce772f6d5ea849ef9218c4d534) --- source3/libsmb/cliconnect.c | 29 +++++++++++++++++++++-------- source3/libsmb/smbencrypt.c | 12 ++++++++++++ 2 files changed, 33 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ebd25627c1..33e2b28609 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -53,6 +53,9 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, return False; } + /* Lanman2 cannot use SMB signing. */ + cli->sign_info.use_smb_signing = False; + /* if in share level security then don't send a password now */ if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { passlen = 0; @@ -199,6 +202,9 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE|STR_ASCII); + /* Plaintext password cannot use SMB signing. */ + cli->sign_info.use_smb_signing = False; + set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -269,6 +275,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, ntpasslen = 24; SMBencrypt((uchar *)pass,cli->secblob.data,(uchar *)pword); SMBNTencrypt((uchar *)pass,cli->secblob.data,(uchar *)ntpword); + cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword); } else { memcpy(pword, pass, passlen); memcpy(ntpword, ntpass, ntpasslen); @@ -339,6 +346,9 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); + /* Extended security cannot use SMB signing (for now). */ + cli->sign_info.use_smb_signing = False; + set_message(cli->outbuf,12,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -522,6 +532,9 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, int i; BOOL got_kerberos_mechanism = False; + /* spnego security cannot use SMB signing (for now). */ + cli->sign_info.use_smb_signing = False; + DEBUG(2,("Doing spnego session setup (blob length=%d)\n", cli->secblob.length)); /* the server might not even do spnego */ @@ -638,18 +651,18 @@ BOOL cli_session_setup(struct cli_state *cli, BOOL cli_ulogoff(struct cli_state *cli) { - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); - SCVAL(cli->outbuf,smb_com,SMBulogoffX); - cli_setup_packet(cli); + memset(cli->outbuf,'\0',smb_size); + set_message(cli->outbuf,2,0,True); + SCVAL(cli->outbuf,smb_com,SMBulogoffX); + cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; - return !cli_is_error(cli); + return !cli_is_error(cli); } /**************************************************************************** diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index de469c0293..29e168f7bf 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -333,6 +333,18 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, return True; } +/*********************************************************** + SMB signing - setup the MAC key. +************************************************************/ + +void cli_calculate_mac_key(struct cli_state *cli, const unsigned char *ntpasswd, const uchar resp[24]) +{ + /* Get first 16 bytes. */ + E_md4hash(ntpasswd,&cli->sign_info.mac_key[0]); + memcpy(&cli->sign_info.mac_key[16],resp,24); + cli->sign_info.mac_key_len = 40; +} + /*********************************************************** SMB signing - calculate a MAC to send. ************************************************************/ -- cgit From 59e0dff0c78add442cb60e72ca7cad7eb1bc7219 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Jun 2002 23:16:00 +0000 Subject: Fix spelling typo. Jeremy. (This used to be commit 0e7e8d44627ad9645a90e96001f8550b68b67a62) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 5f42148078..e7e88687b8 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -120,7 +120,7 @@ BOOL cli_send_smb(struct cli_state *cli) if (cli->fd == -1) return False; - if (SVAL(cli->outbuf,smb_flg2) & FLAGS2_SMB_SECUIRTY_SIGNITURES) + if (SVAL(cli->outbuf,smb_flg2) & FLAGS2_SMB_SECURITY_SIGNATURES) cli_caclulate_sign_mac(cli); len = smb_len(cli->outbuf) + 4; @@ -162,7 +162,7 @@ void cli_setup_packet(struct cli_state *cli) flags2 |= FLAGS2_EXTENDED_SECURITY; } if (cli->sign_info.use_smb_signing) - flags2 |= FLAGS2_SMB_SECUIRTY_SIGNITURES; + flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; SSVAL(cli->outbuf,smb_flg2, flags2); } } -- cgit From 60ad5b69808c0ebfecd13c8f741f4e5687742899 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 16 Jun 2002 04:21:56 +0000 Subject: Fix up some of the SMB signing code: The problem was that *all* packets were being signed, even packets before signing was set up. (This broke the session request). This fixes it to be an 'opt in' measure - that is, we only attempt to sign things after we have got a valid, non-guest session setup as per the CIFS spec. I've not tested this against an MS server, becouse my VMware is down, but at least it doesn't break the build farm any more. Andrew Bartlett (This used to be commit 1dc5a8765876c1ca822e454651f8fd4a551965e9) --- source3/libsmb/cliconnect.c | 41 ++++++++++++++++++++++++----------------- source3/libsmb/clientgen.c | 3 +-- source3/libsmb/clireadwrite.c | 11 +++++++++++ source3/libsmb/smbencrypt.c | 10 ++++++++++ 4 files changed, 46 insertions(+), 19 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 33e2b28609..135238b9a7 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -144,9 +144,6 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) char *p; uint32 capabilities = cli_session_setup_capabilities(cli); - /* Guest cannot use SMB signing. */ - cli->sign_info.use_smb_signing = False; - set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -202,9 +199,6 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE|STR_ASCII); - /* Plaintext password cannot use SMB signing. */ - cli->sign_info.use_smb_signing = False; - set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -275,12 +269,15 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, ntpasslen = 24; SMBencrypt((uchar *)pass,cli->secblob.data,(uchar *)pword); SMBNTencrypt((uchar *)pass,cli->secblob.data,(uchar *)ntpword); - cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword); } else { memcpy(pword, pass, passlen); memcpy(ntpword, ntpass, ntpasslen); } + if (cli->sign_info.negotiated_smb_signing) { + cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword); + } + /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); @@ -311,10 +308,15 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, show_msg(cli->inbuf); + if (cli_is_error(cli) || SVAL(cli->inbuf,smb_vwv2) /* guest */) { + /* We only use it if we have a successful non-guest connect */ + cli->sign_info.use_smb_signing = False; + } + if (cli_is_error(cli)) { return False; } - + /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -346,9 +348,6 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); - /* Extended security cannot use SMB signing (for now). */ - cli->sign_info.use_smb_signing = False; - set_message(cli->outbuf,12,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -813,6 +812,11 @@ BOOL cli_negprot(struct cli_state *cli) int numprots; int plength; + if (cli->sign_info.use_smb_signing) { + DEBUG(0, ("Cannot send negprot again, particularly after setting up SMB Signing\n")); + return False; + } + if (cli->protocol < PROTOCOL_NT1) { cli->use_spnego = False; } @@ -879,10 +883,10 @@ BOOL cli_negprot(struct cli_state *cli) /* A way to attempt to force SMB signing */ if (getenv("CLI_FORCE_SMB_SIGNING")) - cli->sign_info.use_smb_signing = True; - - if (cli->sign_info.use_smb_signing && !(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) - cli->sign_info.use_smb_signing = False; + cli->sign_info.negotiated_smb_signing = True; + + if (cli->sign_info.negotiated_smb_signing && !(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) + cli->sign_info.negotiated_smb_signing = False; } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->use_spnego = False; @@ -896,13 +900,11 @@ BOOL cli_negprot(struct cli_state *cli) cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf)); - cli->sign_info.use_smb_signing = False; } else { /* the old core protocol */ cli->use_spnego = False; cli->sec_mode = 0; cli->serverzone = TimeDiff(time(NULL)); - cli->sign_info.use_smb_signing = False; } cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); @@ -929,6 +931,11 @@ BOOL cli_session_request(struct cli_state *cli, /* 445 doesn't have session request */ if (cli->port == 445) return True; + if (cli->sign_info.use_smb_signing) { + DEBUG(0, ("Cannot send session resquest again, particularly after setting up SMB Signing\n")); + return False; + } + /* send a session request (RFC 1002) */ memcpy(&(cli->calling), calling, sizeof(*calling)); memcpy(&(cli->called ), called , sizeof(*called )); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e7e88687b8..c9500ead5d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -120,8 +120,7 @@ BOOL cli_send_smb(struct cli_state *cli) if (cli->fd == -1) return False; - if (SVAL(cli->outbuf,smb_flg2) & FLAGS2_SMB_SECURITY_SIGNATURES) - cli_caclulate_sign_mac(cli); + cli_caclulate_sign_mac(cli); len = smb_len(cli->outbuf) + 4; diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 6fce1c039b..756a6cce2f 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -128,6 +128,11 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ } #if 0 /* relies on client_recieve_smb(), now a static in libsmb/clientgen.c */ + +/* This call is INCOMPATIBLE with SMB signing. If you remove the #if 0 + you must fix ensure you don't attempt to sign the packets - data + *will* be currupted */ + /**************************************************************************** Issue a single SMBreadraw and don't wait for a reply. ****************************************************************************/ @@ -135,6 +140,12 @@ Issue a single SMBreadraw and don't wait for a reply. static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset, size_t size, int i) { + + if (!cli->sign_info.use_smb_signing) { + DEBUG(0, ("Cannot use readraw and SMB Signing\n")); + return False; + } + memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 29e168f7bf..9ae6da0ced 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -343,6 +343,8 @@ void cli_calculate_mac_key(struct cli_state *cli, const unsigned char *ntpasswd, E_md4hash(ntpasswd,&cli->sign_info.mac_key[0]); memcpy(&cli->sign_info.mac_key[16],resp,24); cli->sign_info.mac_key_len = 40; + cli->sign_info.use_smb_signing = True; + } /*********************************************************** @@ -354,6 +356,14 @@ void cli_caclulate_sign_mac(struct cli_state *cli) unsigned char calc_md5_mac[16]; struct MD5Context md5_ctx; + if (!cli->sign_info.use_smb_signing) { + return; + } + + /* These calls are INCONPATIBLE with SMB signing */ + cli->readbraw_supported = False; + cli->writebraw_supported = False; + /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. -- cgit From a54afa45be41a46432470b6fa3f29050f09b47ba Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 16 Jun 2002 05:03:11 +0000 Subject: Two things: Check how many paramaters that the LDAP libs take for the rebind proc (some give an extra paramter to pass a void* paramater) and some small changes for the SMB signing code to reset things when the signing starts, and to 'turn off' signing if the session setup failed. Andrew Bartlett (This used to be commit a8805a34e5d96eeb5ffe15681b241d5a449a6144) --- source3/libsmb/cliconnect.c | 11 ++++++----- source3/libsmb/smbencrypt.c | 10 ++++++---- 2 files changed, 12 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 135238b9a7..893d194a87 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -258,6 +258,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, uint32 capabilities = cli_session_setup_capabilities(cli); fstring pword, ntpword; char *p; + BOOL tried_signing = False; if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) { return False; @@ -269,15 +270,15 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, ntpasslen = 24; SMBencrypt((uchar *)pass,cli->secblob.data,(uchar *)pword); SMBNTencrypt((uchar *)pass,cli->secblob.data,(uchar *)ntpword); + if (!cli->sign_info.use_smb_signing && cli->sign_info.negotiated_smb_signing) { + cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword); + tried_signing = True; + } } else { memcpy(pword, pass, passlen); memcpy(ntpword, ntpass, ntpasslen); } - if (cli->sign_info.negotiated_smb_signing) { - cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword); - } - /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); @@ -308,7 +309,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, show_msg(cli->inbuf); - if (cli_is_error(cli) || SVAL(cli->inbuf,smb_vwv2) /* guest */) { + if (tried_signing && (cli_is_error(cli) || SVAL(cli->inbuf,smb_vwv2) /* guest */)) { /* We only use it if we have a successful non-guest connect */ cli->sign_info.use_smb_signing = False; } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 9ae6da0ced..95434d0ae4 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -345,6 +345,12 @@ void cli_calculate_mac_key(struct cli_state *cli, const unsigned char *ntpasswd, cli->sign_info.mac_key_len = 40; cli->sign_info.use_smb_signing = True; + /* These calls are INCONPATIBLE with SMB signing */ + cli->readbraw_supported = False; + cli->writebraw_supported = False; + + /* Reset the sequence number in case we had a previous (aborted) attempt */ + cli->sign_info.send_seq_num = 0; } /*********************************************************** @@ -360,10 +366,6 @@ void cli_caclulate_sign_mac(struct cli_state *cli) return; } - /* These calls are INCONPATIBLE with SMB signing */ - cli->readbraw_supported = False; - cli->writebraw_supported = False; - /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. -- cgit From 904533dc9e1948adcd4df5f2a771d20bedb0f520 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 21 Jun 2002 17:23:20 +0000 Subject: Don't use uint. It doesn't exist on some platforms and we don't define it. Replaced with "unsigned int". Jeremy. (This used to be commit 5841ca54b6a8c36f3d76c12570ff8f2211ed2363) --- source3/libsmb/cli_samr.c | 2 +- source3/libsmb/cliconnect.c | 8 ++++++++ source3/libsmb/clifile.c | 2 +- source3/libsmb/clirap2.c | 10 +++++----- 4 files changed, 15 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index dfc4ccf706..91577b3325 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -407,7 +407,7 @@ NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx, SAMR_Q_QUERY_USERALIASES q; SAMR_R_QUERY_USERALIASES r; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint ptr=1; + unsigned int ptr=1; ZERO_STRUCT(q); ZERO_STRUCT(r); diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 893d194a87..cc9821dc29 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -634,10 +634,12 @@ BOOL cli_session_setup(struct cli_state *cli, return cli_session_setup_plaintext(cli, user, pass, workgroup); } +#if 0 /* JRATEST for signing. */ /* if the server supports extended security then use SPNEGO */ if (cli->capabilities & CAP_EXTENDED_SECURITY) { return cli_session_setup_spnego(cli, user, pass, workgroup); } +#endif /* otherwise do a NT1 style session setup */ return cli_session_setup_nt1(cli, user, @@ -822,6 +824,10 @@ BOOL cli_negprot(struct cli_state *cli) cli->use_spnego = False; } +#if 1 /* JRA SIGN TEST */ + cli->use_spnego = False; +#endif + memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ @@ -886,8 +892,10 @@ BOOL cli_negprot(struct cli_state *cli) if (getenv("CLI_FORCE_SMB_SIGNING")) cli->sign_info.negotiated_smb_signing = True; +#if 0 if (cli->sign_info.negotiated_smb_signing && !(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) cli->sign_info.negotiated_smb_signing = False; +#endif } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->use_spnego = False; diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 05843ac5de..a47c956a55 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -76,7 +76,7 @@ static BOOL cli_link_internal(struct cli_state *cli, const char *fname_src, cons uint32 unix_perms_to_wire(mode_t perms) { - uint ret = 0; + unsigned int ret = 0; ret |= ((perms & S_IXOTH) ? UNIX_X_OTH : 0); ret |= ((perms & S_IWOTH) ? UNIX_W_OTH : 0); diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 00cd4b15f3..9c3ec212d5 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -1493,7 +1493,7 @@ int cli_NetPrintQEnum(struct cli_state *cli, for (j=0;j Date: Tue, 25 Jun 2002 07:58:29 +0000 Subject: Kill off unnecessary cast. (This used to be commit 658e853bc6914113dcd4f67d7a1d2761372b562d) --- source3/libsmb/trust_passwd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index 51ffa1dd95..fd98e8dca9 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -71,7 +71,7 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); new_trust_passwd = talloc_strdup(mem_ctx, str); - E_md4hash((uchar *)new_trust_passwd, new_trust_passwd_hash); + E_md4hash(new_trust_passwd, new_trust_passwd_hash); nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash, new_trust_passwd_hash); @@ -96,7 +96,8 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx already setup the connection to the NETLOGON pipe **********************************************************/ -NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, char *domain) +NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *domain) { unsigned char old_trust_passwd_hash[16]; char *up_domain; -- cgit From 07465761137adf756d771fa1f8592c294488e779 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 25 Jun 2002 08:57:24 +0000 Subject: Update cli_full_connection() to take a 'flags' paramater, and try to get a few more places to use it. Andrew Bartlett (This used to be commit 23689b0746d5ab030d8693abf71dd2e80ec1d7c7) --- source3/libsmb/cliconnect.c | 41 ++++++++++++++++++++++++++--------------- source3/libsmb/trust_passwd.c | 3 ++- 2 files changed, 28 insertions(+), 16 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index cc9821dc29..c621d9a34e 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. client connect/disconnect routines Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Andrew Barteltt 2001-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 @@ -1096,7 +1097,7 @@ static void init_creds(struct ntuser_creds *creds, char* username, @param dest_host The netbios name of the remote host @param dest_ip (optional) The the destination IP, NULL for name based lookup @param port (optional) The destination port (0 for default) - @param service The share to make the connection to. Should be 'unqualified' in any way. + @param service (optional) The share to make the connection to. Should be 'unqualified' in any way. @param service_type The 'type' of serivice. @param user Username, unix string @param domain User's domain @@ -1104,11 +1105,12 @@ static void init_creds(struct ntuser_creds *creds, char* username, */ NTSTATUS cli_full_connection(struct cli_state **output_cli, - const char *my_name, const char *dest_host, + const char *my_name, + const char *dest_host, struct in_addr *dest_ip, int port, char *service, char *service_type, char *user, char *domain, - char *password) + char *password, int flags) { struct ntuser_creds creds; NTSTATUS nt_status; @@ -1123,17 +1125,15 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, SMB_ASSERT("output_cli for cli_full_connection was NULL.\n"); } - *output_cli = NULL; - if (!my_name) my_name = global_myname; - make_nmb_name(&calling, my_name, 0x0); - make_nmb_name(&called , dest_host, 0x20); - if (!(cli = cli_initialise(NULL))) return NT_STATUS_NO_MEMORY; + make_nmb_name(&calling, my_name, 0x0); + make_nmb_name(&called , dest_host, 0x20); + if (cli_set_port(cli, port) != port) { cli_shutdown(cli); return NT_STATUS_UNSUCCESSFUL; @@ -1172,6 +1172,12 @@ again: return NT_STATUS_UNSUCCESSFUL; } + if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) { + cli->use_spnego = False; + } else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) { + cli->use_kerberos = True; + } + if (!cli_negprot(cli)) { DEBUG(1,("failed negprot\n")); nt_status = NT_STATUS_UNSUCCESSFUL; @@ -1182,18 +1188,23 @@ again: if (!cli_session_setup(cli, user, password, strlen(password)+1, password, strlen(password)+1, domain)) { - DEBUG(1,("failed session setup\n")); - nt_status = cli_nt_error(cli); - cli_shutdown(cli); - if (NT_STATUS_IS_OK(nt_status)) - nt_status = NT_STATUS_UNSUCCESSFUL; - return nt_status; + if (!(flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK) + || cli_session_setup(cli, "", "", 0, + "", 0, domain)) { + } else { + nt_status = cli_nt_error(cli); + DEBUG(1,("failed session setup with %s\n", nt_errstr(nt_status))); + cli_shutdown(cli); + if (NT_STATUS_IS_OK(nt_status)) + nt_status = NT_STATUS_UNSUCCESSFUL; + return nt_status; + } } if (service) { if (!cli_send_tconX(cli, service, service_type, (char*)password, strlen(password)+1)) { - DEBUG(1,("failed tcon_X\n")); + DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status))); nt_status = cli_nt_error(cli); cli_shutdown(cli); if (NT_STATUS_IS_OK(nt_status)) { diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index fd98e8dca9..7491f15f52 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -77,7 +77,8 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx new_trust_passwd_hash); if (NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("%s : change_trust_account_password: Changed password.\n", timestring(False))); + DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", + timestring(False))); /* * Return the result of trying to write the new password * back into the trust account file. -- cgit From 12658bc7257732b28ffe8e18a47b1527df693510 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 26 Jun 2002 06:39:18 +0000 Subject: reverted some bogus test code that jeremy accidentally committed (This used to be commit 6b28ca8bd2a6613989bb23be951836d173296197) --- source3/libsmb/cliconnect.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index c621d9a34e..50d9edf5b2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -635,12 +635,10 @@ BOOL cli_session_setup(struct cli_state *cli, return cli_session_setup_plaintext(cli, user, pass, workgroup); } -#if 0 /* JRATEST for signing. */ /* if the server supports extended security then use SPNEGO */ if (cli->capabilities & CAP_EXTENDED_SECURITY) { return cli_session_setup_spnego(cli, user, pass, workgroup); } -#endif /* otherwise do a NT1 style session setup */ return cli_session_setup_nt1(cli, user, @@ -825,10 +823,6 @@ BOOL cli_negprot(struct cli_state *cli) cli->use_spnego = False; } -#if 1 /* JRA SIGN TEST */ - cli->use_spnego = False; -#endif - memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ @@ -893,10 +887,8 @@ BOOL cli_negprot(struct cli_state *cli) if (getenv("CLI_FORCE_SMB_SIGNING")) cli->sign_info.negotiated_smb_signing = True; -#if 0 if (cli->sign_info.negotiated_smb_signing && !(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) cli->sign_info.negotiated_smb_signing = False; -#endif } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->use_spnego = False; -- cgit From 07f35f68e00b48ad6ec4d18c628d0bb57bad85ef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 26 Jun 2002 06:44:37 +0000 Subject: - completely rewrote the wins_srv.c code. It is now much simpler, and gives us a good grounding to properly support multiple wins servers for different interfaces (which will be coming soon ...) - fixed our wins registration failover code to actually do failover! We were not trying to register with a secondary wins server at all when the primary was down. We now fallback correctly. - fixed the multi-homed name registration packets so that they work even in a non-connected network (ie. when one of our interfaces is not routable from the wins server. Yes, this really happens in the real world). (This used to be commit a049360d5b0d95a935b06aad43efc17d34de46dc) --- source3/libsmb/namequery.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index a97270b7d4..d709f997f5 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -603,10 +603,12 @@ BOOL name_register_wins(const char *name, int name_type) if (0 == wins_srv_count()) return False; + sendto_ip = wins_srv_ip(); + if( DEBUGLVL( 4 ) ) { dbgtext( "name_register_wins: Registering my name %s ", name ); - dbgtext( "with WINS server %s.\n", wins_srv_name() ); + dbgtext( "with WINS server %s.\n", inet_ntoa(sendto_ip)); } sock = open_socket_in( SOCK_DGRAM, 0, 3, @@ -616,8 +618,6 @@ BOOL name_register_wins(const char *name, int name_type) set_socket_options(sock, "SO_BROADCAST"); /* ????! crh */ - sendto_ip = wins_srv_ip(); - if (num_interfaces > 1) { for (i = 0; i < num_interfaces; i++) { -- cgit From b20ca8b8683e584d7a1843b07f262da34b6dca19 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 26 Jun 2002 08:09:28 +0000 Subject: removed the wins name registration code from libsmbclient it is *completely* bogus for our client code to be doing wins registrations. Not only is it slow as hell (think about when a wins server is down) but how the heck is going to answer the queries that will later come in for our name? And what happens when libsmbclient sends registrations and nmbd then gets the WACK response from the wins server? we end up losing our name! Name registration is a job for nmbd, not for clients. (This used to be commit 62774923ffdce15eded0f37ba99e33e9cd7a358c) --- source3/libsmb/libsmbclient.c | 2 - source3/libsmb/namequery.c | 385 +++++++++++++++++------------------------- 2 files changed, 158 insertions(+), 229 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 237701b968..3066f72280 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -523,8 +523,6 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug) } DEBUG(0,("Using netbios name %s.\n", my_netbios_name)); - name_register_wins(my_netbios_name, 0); - /* * Now initialize the file descriptor array and figure out what the * max open files is, so we can return FD's that are above the max diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index d709f997f5..c85c8c48df 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -307,171 +307,171 @@ 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 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; - - 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--; - + 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; + + 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 */ + 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 */ dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode ); - switch( nmb2->header.rcode ) { - case 0x01: - dbgtext( "Request was invalidly formatted.\n" ); - break; - case 0x02: - dbgtext( "Problem with NBNS, cannot process name.\n"); - break; - case 0x03: - dbgtext( "The name requested does not exist.\n" ); - break; - case 0x04: - dbgtext( "Unsupported request error.\n" ); - break; - case 0x05: - dbgtext( "Query refused error.\n" ); - break; - default: - dbgtext( "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 + switch( nmb2->header.rcode ) { + case 0x01: + dbgtext( "Request was invalidly formatted.\n" ); + break; + case 0x02: + dbgtext( "Problem with NBNS, cannot process name.\n"); + break; + case 0x03: + dbgtext( "The name requested does not exist.\n" ); + break; + case 0x04: + dbgtext( "Unsupported request error.\n" ); + break; + case 0x05: + dbgtext( "Query refused error.\n" ); + break; + default: + dbgtext( "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) { + 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; - } - } + 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; + } + } - /* Reach here if we've timed out waiting for replies.. */ - if( !bcast && !found ) { - /* Timed out wating for WINS server to respond. Mark it dead. */ - wins_srv_died( to_ip ); - } + /* Reach here if we've timed out waiting for replies.. */ + if (!bcast && !found) { + /* Timed out wating for WINS server to respond. Mark it dead. */ + wins_srv_died( to_ip ); + } - return ip_list; + return ip_list; } /******************************************************** @@ -583,75 +583,6 @@ void endlmhosts(XFILE *fp) x_fclose(fp); } -BOOL name_register_wins(const char *name, int name_type) -{ - int sock, i, return_count; - int num_interfaces = iface_count(); - struct in_addr sendto_ip; - - /* - * Check if we have any interfaces, prevents a segfault later - */ - - if (num_interfaces <= 0) - return False; /* Should return some indication of the problem */ - - /* - * Do a broadcast register ... - */ - - if (0 == wins_srv_count()) - return False; - - sendto_ip = wins_srv_ip(); - - if( DEBUGLVL( 4 ) ) - { - dbgtext( "name_register_wins: Registering my name %s ", name ); - dbgtext( "with WINS server %s.\n", inet_ntoa(sendto_ip)); - } - - sock = open_socket_in( SOCK_DGRAM, 0, 3, - interpret_addr("0.0.0.0"), True ); - - if (sock == -1) return False; - - set_socket_options(sock, "SO_BROADCAST"); /* ????! crh */ - - if (num_interfaces > 1) { - - for (i = 0; i < num_interfaces; i++) { - - if (!name_register(sock, name, name_type, *iface_n_ip(i), - NMB_NAME_MULTIHOMED_REG_OPCODE, - True, sendto_ip, &return_count)) { - - close(sock); - return False; - - } - - } - - } - else { - - if (!name_register(sock, name, name_type, *iface_n_ip(0), - NMB_NAME_REG_OPCODE, - True, sendto_ip, &return_count)) { - - close(sock); - return False; - - } - - } - - close(sock); - - return True; - -} /******************************************************** Resolve via "bcast" method. -- cgit From caeaa0acb02f681be6025e3eafded223983960a0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 26 Jun 2002 12:17:11 +0000 Subject: This commit finally gives us multiple wins server groups. We now accept an extended syntax for 'wins server' like this: wins server = group1:192.168.2.10 group2:192.168.3.99 group1:192.168.0.1 The tags before the IPs don't mean anything, they are just a way of grouping IPs together. If you use the old syntax (ie. no ':') then an implicit group name of '*' is used. In general I'd recommend people use interface names for the group names, but it doesn't matter much. When we register in nmbd we try to register all our IPs with each group of WINS servers. We keep trying until all of them are registered with every group, falling back to the failover WINS servers for each group as we go. When we do a WINS lookup we try each of the WINS servers for each group. If a WINS server for a group gives a negative answer then we give up on that group and move to the next group. If it times out then we move to the next failover wins server in the group. In either case, if a WINS server doesn't respond then we mark it dead for 10 minutes, to prevent lengthy waits for dead servers. (This used to be commit e125f06058b6b51382cf046b1dbb30728b8aeda5) --- source3/libsmb/namequery.c | 111 +++++++++++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 43 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index c85c8c48df..2cdcd49b91 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -302,10 +302,12 @@ BOOL name_register(int fd, const char *name, int name_type, 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) + struct in_addr to_ip, int *count, int *flags, + BOOL *timed_out) { BOOL found=False; int i, retries = 3; @@ -315,6 +317,10 @@ struct in_addr *name_query(int fd,const char *name,int name_type, struct packet_struct *p2; struct nmb_packet *nmb = &p.packet.nmb; struct in_addr *ip_list = NULL; + + if (timed_out) { + *timed_out = False; + } memset((char *)&p,'\0',sizeof(p)); (*count) = 0; @@ -465,10 +471,8 @@ struct in_addr *name_query(int fd,const char *name,int name_type, } } - /* Reach here if we've timed out waiting for replies.. */ - if (!bcast && !found) { - /* Timed out wating for WINS server to respond. Mark it dead. */ - wins_srv_died( to_ip ); + if (timed_out) { + *timed_out = True; } return ip_list; @@ -619,7 +623,7 @@ BOOL name_resolve_bcast(const char *name, int name_type, /* 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); + True, sendto_ip, return_count, &flags, NULL); if(*return_ip_list != NULL) { close(sock); return True; @@ -637,59 +641,80 @@ BOOL name_resolve_bcast(const char *name, int name_type, static BOOL resolve_wins(const char *name, int name_type, struct in_addr **return_iplist, int *return_count) { - int sock; - struct in_addr wins_ip; - BOOL wins_ismyip; + int sock, t, i; + char **wins_tags; *return_iplist = NULL; *return_count = 0; - /* - * "wins" means do a unicast lookup to the WINS server. - * Ignore if there is no WINS server specified or if the - * WINS server is one of our interfaces (if we're being - * called from within nmbd - we can't do this call as we - * would then block). - */ - DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type)); - if (lp_wins_support()) { - /* - * We're providing WINS support. Call ourselves so - * long as we're not nmbd. - */ - extern struct in_addr loopback_ip; - wins_ip = loopback_ip; - wins_ismyip = True; - } else if( wins_srv_count() < 1 ) { + if (wins_srv_count() < 1) { DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n")); return False; - } else { - wins_ip = wins_srv_ip(); - wins_ismyip = ismyip(wins_ip); } - DEBUG(3, ("resolve_wins: WINS server == <%s>\n", inet_ntoa(wins_ip)) ); - if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) { - int flags; - sock = open_socket_in( SOCK_DGRAM, 0, 3, - interpret_addr(lp_socket_address()), - True ); - if (sock != -1) { - *return_iplist = name_query( sock, name, - name_type, False, - True, wins_ip, - return_count, &flags); - if(*return_iplist != NULL) { - close(sock); - return True; + /* 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; + } + + /* in the worst case we will try every wins server with every + tag! */ + for (t=0; wins_tags && wins_tags[t]; t++) { + for (i=0; i Date: Wed, 26 Jun 2002 12:49:59 +0000 Subject: resolve_wins() now needs to be a public function (This used to be commit 0bce9af615db2eb7e95887ab6b95655d7771dac2) --- source3/libsmb/namequery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 2cdcd49b91..7cd7d70815 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -638,8 +638,8 @@ BOOL name_resolve_bcast(const char *name, int name_type, Resolve via "wins" method. *********************************************************/ -static BOOL resolve_wins(const char *name, int name_type, - struct in_addr **return_iplist, int *return_count) +BOOL resolve_wins(const char *name, int name_type, + struct in_addr **return_iplist, int *return_count) { int sock, t, i; char **wins_tags; -- cgit From cb8dcb0b60d0bdd13ef20cad9784d783c62775dd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Jun 2002 00:13:20 +0000 Subject: Using 1 for a tdb hash size makes for slow inserts.... Jeremy. (This used to be commit d015c08100bf467e3f83143586a234989eca1a49) --- source3/libsmb/unexpected.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index f74a05f75f..4fc3914481 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -46,7 +46,7 @@ void unexpected_packet(struct packet_struct *p) int len=0; if (!tdbd) { - tdbd = tdb_open_log(lock_path("unexpected.tdb"), 1, + tdbd = tdb_open_log(lock_path("unexpected.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, O_RDWR | O_CREAT, 0644); if (!tdbd) { -- cgit From 223ddc3f2daf25b16ce60230336747d5fab61e39 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 27 Jun 2002 14:37:17 +0000 Subject: The next phase in the WINS rewrite! We now cope wiith multiple WINS groups and multiple failover servers for release and refresh as well as registration. We also do the regitrations in the same fashion as W2K does, where we don't try to register the next IP in the list for a name until the WINS server has acked the previos IP. This prevents us flooding the WINS server and also seems to make for much more reliable multi-homed registration. I also changed the dead WINS server code to mark pairs of IPs dead, not individual IPs. The idea is that a WINS server might be dead from the point of view of one of our interfaces, but not another, so we need to keep talking to it on one while moving onto a failover WINS server on the other interface. This copes much better with partial LAN outages and weird routing tables. (This used to be commit 313f2c9ff7a513802e4f893324865e70912d419e) --- source3/libsmb/namequery.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 7cd7d70815..2c6fb2fd71 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -637,12 +637,12 @@ BOOL name_resolve_bcast(const char *name, int name_type, /******************************************************** Resolve via "wins" method. *********************************************************/ - BOOL resolve_wins(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; *return_iplist = NULL; *return_count = 0; @@ -662,15 +662,19 @@ BOOL resolve_wins(const char *name, int name_type, 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++) { - for (i=0; i Date: Thu, 27 Jun 2002 14:54:01 +0000 Subject: fixed a link problem with global_in_nmbd (This used to be commit 9a3e323ec261a1ee3a83f8c558583c3d4a53e06a) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 2c6fb2fd71..75e2458964 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -22,7 +22,7 @@ #include "includes.h" /* nmbd.c sets this to True. */ -BOOL global_in_nmbd = False; +extern BOOL global_in_nmbd; /**************************************************************************** generate a random trn_id -- cgit From 452eb38df0553886313c9b19a945385d853e19ab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Jun 2002 00:17:15 +0000 Subject: Proper merge of all the working printing stuff from APPLIANCE_HEAD. Now let's keep this in sync ! Jeremy. (This used to be commit 3603cd4947df2c10df604447dc542932cb9e5d5a) --- source3/libsmb/cli_spoolss.c | 8 +- source3/libsmb/cli_spoolss_notify.c | 223 ++++++++++++++++++++++++++++++++++++ 2 files changed, 227 insertions(+), 4 deletions(-) create mode 100644 source3/libsmb/cli_spoolss_notify.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 48094f8179..18e17758d6 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1556,11 +1556,11 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, switch(level) { case 1: decode_jobs_1(mem_ctx, r.buffer, r.returned, - &ctr->job.job_info_1); + ctr->job.job_info_1); break; case 2: decode_jobs_2(mem_ctx, r.buffer, r.returned, - &ctr->job.job_info_2); + ctr->job.job_info_2); break; default: DEBUG(3, ("unsupported info level %d", level)); @@ -1669,10 +1669,10 @@ WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, switch(level) { case 1: - decode_jobs_1(mem_ctx, r.buffer, 1, &ctr->job.job_info_1); + decode_jobs_1(mem_ctx, r.buffer, 1, ctr->job.job_info_1); break; case 2: - decode_jobs_2(mem_ctx, r.buffer, 1, &ctr->job.job_info_2); + decode_jobs_2(mem_ctx, r.buffer, 1, ctr->job.job_info_2); break; default: DEBUG(3, ("unsupported info level %d", level)); diff --git a/source3/libsmb/cli_spoolss_notify.c b/source3/libsmb/cli_spoolss_notify.c new file mode 100644 index 0000000000..922b0fbb1d --- /dev/null +++ b/source3/libsmb/cli_spoolss_notify.c @@ -0,0 +1,223 @@ +/* + Unix SMB/CIFS implementation. + RPC pipe client + + Copyright (C) Gerald Carter 2001-2002, + Copyright (C) Tim Potter 2000-2002, + Copyright (C) Andrew Tridgell 1994-2000, + Copyright (C) Luke Kenneth Casson Leighton 1996-2000, + Copyright (C) Jean-Francois Micouleau 1999-2000. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* + * SPOOLSS Client RPC's used by servers as the notification + * back channel. + */ + +/* Send a ReplyOpenPrinter request. This rpc is made by the printer + server to the printer client in response to a rffpcnex request. + The rrfpcnex request names a printer and a handle (the printerlocal + value) and this rpc establishes a back-channel over which printer + notifications are performed. */ + +WERROR cli_spoolss_reply_open_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *printer, uint32 printerlocal, uint32 type, + POLICY_HND *handle) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_REPLYOPENPRINTER q; + SPOOL_R_REPLYOPENPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + /* Initialise input parameters */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + make_spoolss_q_replyopenprinter(&q, printer, printerlocal, type); + + /* Marshall data and send request */ + + if (!spoolss_io_q_replyopenprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli, SPOOLSS_REPLYOPENPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_replyopenprinter("", &r, &rbuf, 0)) + goto done; + + /* Return result */ + + memcpy(handle, &r.handle, sizeof(r.handle)); + result = r.status; + +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Close a back-channel notification connection */ + +WERROR cli_spoolss_reply_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *handle) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_REPLYCLOSEPRINTER q; + SPOOL_R_REPLYCLOSEPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + /* Initialise input parameters */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + make_spoolss_q_reply_closeprinter(&q, handle); + + /* Marshall data and send request */ + + if (!spoolss_io_q_replycloseprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli, SPOOLSS_REPLYCLOSEPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_replycloseprinter("", &r, &rbuf, 0)) + goto done; + + /* Return result */ + + result = r.status; + +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/********************************************************************* + This SPOOLSS_ROUTERREPLYPRINTER function is used to send a change + notification event when the registration **did not** use + SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor. + Also see cli_spolss_reply_rrpcn() + *********************************************************************/ + +WERROR cli_spoolss_routerreplyprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 condition, uint32 change_id) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ROUTERREPLYPRINTER q; + SPOOL_R_ROUTERREPLYPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + /* Initialise input parameters */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + make_spoolss_q_routerreplyprinter(&q, pol, condition, change_id); + + /* Marshall data and send request */ + + if (!spoolss_io_q_routerreplyprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli, SPOOLSS_ROUTERREPLYPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_routerreplyprinter("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/********************************************************************* + This SPOOLSS_REPLY_RRPCN function is used to send a change + notification event when the registration **did** use + SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor + Also see cli_spoolss_routereplyprinter() + *********************************************************************/ + +WERROR cli_spoolss_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 notify_data_len, + SPOOL_NOTIFY_INFO_DATA *notify_data, + uint32 change_low, uint32 change_high) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_REPLY_RRPCN q; + SPOOL_R_REPLY_RRPCN r; + WERROR result = W_ERROR(ERRgeneral); + SPOOL_NOTIFY_INFO notify_info; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + ZERO_STRUCT(notify_info); + + /* Initialise input parameters */ + + notify_info.version = 0x2; + notify_info.flags = 0x00020000; /* ?? */ + notify_info.count = notify_data_len; + notify_info.data = notify_data; + + /* create and send a MSRPC command with api */ + /* store the parameters */ + + make_spoolss_q_reply_rrpcn(&q, pol, change_low, change_high, + ¬ify_info); + + /* Marshall data and send request */ + + if(!spoolss_io_q_reply_rrpcn("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_RRPCN, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if(!spoolss_io_r_reply_rrpcn("", &r, &rbuf, 0)) + goto done; + + if (r.unknown0 == 0x00080000) + DEBUG(8,("cli_spoolss_reply_rrpcn: I think the spooler resonded that the notification was ignored.\n")); + + result = r.status; + +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 01eec582433744967d35d611e6b153262fa8f9f2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 28 Jun 2002 03:51:31 +0000 Subject: make net join a bit less verbose these errors happen all the time, so they shouldn't be level 0 (This used to be commit abc2aed26c6cb12a86987a3846ca5c9f7df9a5ae) --- source3/libsmb/cli_netlogon.c | 2 +- source3/libsmb/trust_passwd.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 765f19a5fe..4f5ccb1e21 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -197,7 +197,7 @@ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, result = new_cli_net_auth2(cli, sec_chan, 0x000001ff, &srv_chal); if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("cli_nt_setup_creds: auth2 challenge failed %s\n", + DEBUG(1,("cli_nt_setup_creds: auth2 challenge failed %s\n", nt_errstr(result))); } diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index 7491f15f52..3b77f7330e 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -39,7 +39,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ SEC_CHAN_WKSTA : SEC_CHAN_BDC, orig_trust_passwd_hash); if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("just_change_the_password: unable to setup creds (%s)!\n", + DEBUG(1,("just_change_the_password: unable to setup creds (%s)!\n", nt_errstr(result))); return result; } -- cgit From 4b12f559b9fa61309e1a64c8b286136aba9ba3eb Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Mon, 1 Jul 2002 03:42:04 +0000 Subject: The 17-bit length field in the header contains the number of bytes which follow the header, not the full packet size. [Yes, the length field is either 17-bits, or (per the RFCs) it is a 16-bit length field preceeded by an 8-bit flags field of which only the low-order bit may be used. If that bit is set, then add 65536 to the 16-bit length field. (In other words, it's a 17-bit unsigned length field.) ...unless, of course, the transport is native TCP [port 445] in which case the length field *might* be 24-bits wide.] Anyway, the change is a very minor one. We were including the four bytes of the header in the length count and, as a result, sending four bytes of garbage at the end of the SESSION REQUEST packet. Small fix in function cli_session_request(). (This used to be commit cd2b1357066a712efcf87ac61922ef871118e8de) --- source3/libsmb/cliconnect.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 50d9edf5b2..f0b02b97b0 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -952,7 +952,14 @@ BOOL cli_session_request(struct cli_state *cli, name_mangle(cli->calling.name, p, cli->calling.name_type); len += name_len(p); - /* setup the packet length */ + /* setup the packet length + * Remove four bytes from the length count, since the length + * field in the NBT Session Service header counts the number + * of bytes which follow. The cli_send_smb() function knows + * about this and accounts for those four bytes. + * CRH. + */ + len -= 4; _smb_setlen(cli->outbuf,len); SCVAL(cli->outbuf,0,0x81); -- cgit From 2e917ea040d85f06b8e40b6fd178c08ee84797c9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Jul 2002 05:09:29 +0000 Subject: sort name query responses by how far they are from our interface broadcast addresses. This makes it far more likely that we will try to talk to an interface that is routable from one of our interfaces. (This used to be commit bc1a0506868266088ae585a7a5dcb1ac8ca3474d) --- source3/libsmb/namequery.c | 41 +++++++++++++++++++++++++++++++++++++++++ source3/libsmb/nmblib.c | 4 ++-- 2 files changed, 43 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 75e2458964..242601d1da 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -298,6 +298,44 @@ BOOL name_register(int fd, const char *name, int name_type, return True; } + +/* + comparison function used by sort_ip_list +*/ +static int ip_compare(struct in_addr *ip1, struct in_addr *ip2) +{ + int max_bits1=0, max_bits2=0; + int num_interfaces = iface_count(); + int i; + + 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); + } + + 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. @@ -475,6 +513,9 @@ struct in_addr *name_query(int fd,const char *name,int name_type, *timed_out = True; } + /* sort the ip list so we choose close servers first if possible */ + sort_ip_list(ip_list, *count); + return ip_list; } diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 9a37b4252a..ba0d8cee5d 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1045,7 +1045,7 @@ BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name) /**************************************************************************** return the number of bits that match between two 4 character buffers ***************************************************************************/ -static int matching_bits(uchar *p1, uchar *p2) +int matching_quad_bits(uchar *p1, uchar *p2) { int i, j, ret = 0; for (i=0; i<4; i++) { @@ -1071,7 +1071,7 @@ compare two query reply records ***************************************************************************/ static int name_query_comp(uchar *p1, uchar *p2) { - return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip); + return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip); } /**************************************************************************** -- cgit From 3563257247c9444f1b1489fb9f4faba3dc50959e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Jul 2002 05:39:32 +0000 Subject: bias the lookup sorting towards directly reachable IPs (This used to be commit 514b91827a970a0041314af341b8c66a01668e4a) --- source3/libsmb/namequery.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 242601d1da..2bf72fbaac 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -317,6 +317,14 @@ static int ip_compare(struct in_addr *ip1, struct in_addr *ip2) 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; } -- cgit From 9930b0b0650ae3e38c033c28672398425dd8228c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Jul 2002 09:12:41 +0000 Subject: used findstatic.pl to make some variables static and remove some dead code (This used to be commit 91ad9041e9507d36eb3f40c23c5d4df61f139ef0) --- source3/libsmb/namequery.c | 99 ---------------------------------------------- 1 file changed, 99 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 2bf72fbaac..68c09751bd 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -207,97 +207,6 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t return result; } -/**************************************************************************** - Do a NetBIOS name registation to try to claim a name ... -***************************************************************************/ -BOOL name_register(int fd, const char *name, int name_type, - struct in_addr name_ip, int opcode, - BOOL bcast, - struct in_addr to_ip, int *count) -{ - int retries = 3; - struct timeval tval; - struct packet_struct p; - struct packet_struct *p2; - struct nmb_packet *nmb = &p.packet.nmb; - struct in_addr register_ip; - - DEBUG(4, ("name_register: %s as %s on %s\n", name, inet_ntoa(name_ip), inet_ntoa(to_ip))); - - register_ip.s_addr = name_ip.s_addr; /* Fix this ... */ - - memset((char *)&p, '\0', sizeof(p)); - - *count = 0; - - nmb->header.name_trn_id = generate_trn_id(); - nmb->header.opcode = opcode; - nmb->header.response = False; - nmb->header.nm_flags.bcast = False; - nmb->header.nm_flags.recursion_available = False; - nmb->header.nm_flags.recursion_desired = True; /* ? */ - nmb->header.nm_flags.trunc = False; - nmb->header.nm_flags.authoritative = True; - - nmb->header.qdcount = 1; - nmb->header.ancount = 0; - nmb->header.nscount = 0; - nmb->header.arcount = 1; - - make_nmb_name(&nmb->question.question_name, name, name_type); - - nmb->question.question_type = 0x20; - nmb->question.question_class = 0x1; - - /* Now, create the additional stuff for a registration request */ - - if ((nmb->additional = (struct res_rec *)malloc(sizeof(struct res_rec))) == NULL) { - - DEBUG(0, ("name_register: malloc fail for additional record.\n")); - return False; - - } - - memset((char *)nmb->additional, '\0', sizeof(struct res_rec)); - - nmb->additional->rr_name = nmb->question.question_name; - nmb->additional->rr_type = RR_TYPE_NB; - nmb->additional->rr_class = RR_CLASS_IN; - - /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */ - if (nmb->header.nm_flags.bcast) - nmb->additional->ttl = PERMANENT_TTL; - else - nmb->additional->ttl = lp_max_ttl(); - - nmb->additional->rdlength = 6; - - nmb->additional->rdata[0] = NB_MFLAG & 0xFF; - - /* Set the address for the name we are registering. */ - putip(&nmb->additional->rdata[2], ®ister_ip); - - 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 False; - - retries--; - - if ((p2 = receive_nmb_packet(fd, 10, nmb->header.name_trn_id))) { - debug_nmb_packet(p2); - SAFE_FREE(p2); /* No memory leaks ... */ - } - - return True; -} - /* comparison function used by sort_ip_list @@ -1248,14 +1157,6 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */ } -/******************************************************** - Get the IP address list of the Local Master Browsers - ********************************************************/ - -BOOL get_lmb_list(struct in_addr **ip_list, int *count) -{ - return internal_resolve_name( MSBROWSE, 0x1, ip_list, count); -} /******************************************************** Get the IP address list of the PDC/BDC's of a Domain. -- cgit From 4a0fab59cb70c6bdcbfb8bd8d3492cd1e01ca917 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 3 Jul 2002 07:21:07 +0000 Subject: Add my copyright (which I should have added months ago...) (This used to be commit 2d7eccbeb258b4fdd14323a40f9537eb265f73e1) --- source3/libsmb/errormap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index c30db3ad95..a35108c3de 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -2,6 +2,7 @@ * Unix SMB/CIFS implementation. * error mapping functions * Copyright (C) Andrew Tridgell 2001 + * Copyright (C) Andrew Bartlett 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 -- cgit From a19c823c3c21af6267018c62b68cce0937a3da13 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 3 Jul 2002 07:22:45 +0000 Subject: Make these functions static. These are not mentioned in the external header, and appear to be functions for internal use. Richard: please check. Andrew Bartlett (This used to be commit cb61e61a113dede4a0b0f5d31d0ec89c4b6ecd65) --- source3/libsmb/libsmbclient.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 3066f72280..dcf2755c8d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -55,8 +55,8 @@ struct smbc_file { int dir_type, dir_error; }; -int smbc_fstatdir(int fd, struct stat *st); /* Forward decl */ -BOOL smbc_getatr(struct smbc_server *srv, char *path, +static int smbc_fstatdir(int fd, struct stat *st); /* Forward decl */ +static BOOL smbc_getatr(struct smbc_server *srv, char *path, uint16 *mode, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time, SMB_INO_T *ino); @@ -1164,7 +1164,7 @@ int smbc_setup_stat(struct stat *st, char *fname, size_t size, int mode) * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo */ -BOOL smbc_getatr(struct smbc_server *srv, char *path, +static BOOL smbc_getatr(struct smbc_server *srv, char *path, uint16 *mode, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time, SMB_INO_T *ino) @@ -2344,7 +2344,7 @@ int smbc_lseekdir(int fd, off_t offset) * Routine to fstat a dir */ -int smbc_fstatdir(int fd, struct stat *st) +static int smbc_fstatdir(int fd, struct stat *st) { if (!smbc_initialized) { -- cgit From bc418dbbc0a8c342335aa24cb58e18c0f8b48cfa Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 4 Jul 2002 03:32:36 +0000 Subject: Fixed incorrect debug. (This used to be commit dd46ff7619129782963ec6ea727e5d731370ee7d) --- source3/libsmb/cli_netlogon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 4f5ccb1e21..d32e0e77e4 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -43,7 +43,7 @@ NTSTATUS new_cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, /* create and send a MSRPC command with api NET_REQCHAL */ DEBUG(4,("new_cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n", - cli->desthost, global_myname, credstr(clnt_chal->data))); + global_myname, cli->desthost, credstr(clnt_chal->data))); /* store the parameters */ init_q_req_chal(&q, cli->srv_name_slash, global_myname, clnt_chal); -- cgit From 3593e5baf7c3b334da390b027ef7d236ce318ccd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 9 Jul 2002 14:47:03 +0000 Subject: fix declaration of global_in_nmbd (This used to be commit 07de8418369dad1f015369e70e9303fea4130295) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 68c09751bd..18564bccf4 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -22,7 +22,7 @@ #include "includes.h" /* nmbd.c sets this to True. */ -extern BOOL global_in_nmbd; +BOOL global_in_nmbd = False; /**************************************************************************** generate a random trn_id -- cgit From 669358c05f8300dc14cc462a0d00eab86dc0e84a Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Thu, 11 Jul 2002 23:33:00 +0000 Subject: Commit Tom Jansen's changes to head. (This used to be commit d3fdce07ab5955abd1f923127ae9eb5006aea505) --- source3/libsmb/libsmbclient.c | 1718 +++++++++++++++++++++-------------------- 1 file changed, 899 insertions(+), 819 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index dcf2755c8d..77a81c10c8 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1,9 +1,11 @@ /* - Unix SMB/CIFS implementation. + Unix SMB/Netbios implementation. + Version 2.0 SMB client library implementation Copyright (C) Andrew Tridgell 1998 - Copyright (C) Richard Sharpe 2000 + Copyright (C) Richard Sharpe 2000, 2002 Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 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 @@ -21,56 +23,41 @@ */ #include "includes.h" + +/* + * Define this to get the real SMBCFILE and SMBCSRV structures + */ +#define _SMBC_INTERNAL + #include "libsmbclient.h" -/* Structure for servers ... Held here so we don't need an include ... - * May be better to put in an include file +/* + * Functions exported by libsmb_cache.c that we need here */ +int smbc_default_cache_functions(SMBCCTX * context); -struct smbc_server { - struct smbc_server *next, *prev; - struct cli_state cli; - dev_t dev; - char *server_name; - char *share_name; - char *workgroup; - char *username; - BOOL no_pathinfo2; -}; - -/* Keep directory entries in a list */ -struct smbc_dir_list { - struct smbc_dir_list *next; - struct smbc_dirent *dirent; -}; - -struct smbc_file { - int cli_fd; - int smbc_fd; - char *fname; - off_t offset; - struct smbc_server *srv; - BOOL file; - struct smbc_dir_list *dir_list, *dir_end, *dir_next; - int dir_type, dir_error; -}; - -static int smbc_fstatdir(int fd, struct stat *st); /* Forward decl */ -static BOOL smbc_getatr(struct smbc_server *srv, char *path, - uint16 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time, - SMB_INO_T *ino); +/* + * check if an element is part of the list. + * FIXME: Does not belong here ! + * Can anyone put this in a macro in dlinklist.h ? + * -- Tom + */ +static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) { + if (!p || !list) return False; + do { + if (p == list) return True; + list = list->next; + } while (list); + return False; +} extern BOOL in_client; extern pstring global_myname; + +/* + * Is the logging working / configfile read ? + */ static int smbc_initialized = 0; -static smbc_get_auth_data_fn smbc_auth_fn = NULL; -/*static int smbc_debug;*/ -static int smbc_start_fd; -static struct smbc_file **smbc_file_table; -static struct smbc_server *smbc_srvs; -static pstring my_netbios_name; -static pstring smbc_user; /* * Function to parse a path and turn it into components @@ -78,14 +65,14 @@ static pstring smbc_user; * We accept smb://[[[domain;]user[:password@]]server[/share[/path[/file]]]] * * smb:// means show all the workgroups - * smb://name/ means, if name<1D> exists, list servers in workgroup, + * smb://name/ means, if name<1D> or name<1B> exists, list servers in workgroup, * else, if name<20> exists, list all shares for server ... */ static const char *smbc_prefix = "smb:"; static int -smbc_parse_path(const char *fname, char *server, char *share, char *path, +smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, char *path, char *user, char *password) /* FIXME, lengths of strings */ { static pstring s; @@ -121,7 +108,8 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, if (*p == '/') { - strncpy(server, (char *)lp_workgroup(), 16); /* FIXME: Danger here */ + strncpy(server, context->workgroup, + (strlen(context->workgroup) < 16)?strlen(context->workgroup):16); return 0; } @@ -134,8 +122,8 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, */ /* check that '@' occurs before '/', if '/' exists at all */ - q = strchr_m(p, '@'); - r = strchr_m(p, '/'); + q = strchr(p, '@'); + r = strchr(p, '/'); if (q && (!r || q < r)) { pstring username, passwd, domain; char *u = userinfo; @@ -144,13 +132,13 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, username[0] = passwd[0] = domain[0] = 0; - if (strchr_m(u, ';')) { + if (strchr(u, ';')) { next_token(&u, domain, ";", sizeof(fstring)); - + } - if (strchr_m(u, ':')) { + if (strchr(u, ':')) { next_token(&u, username, ":", sizeof(fstring)); @@ -172,9 +160,9 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, } if (!next_token(&p, server, "/", sizeof(fstring))) { - + return -1; - + } if (*p == (char)0) return 0; /* That's it ... */ @@ -196,7 +184,7 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, * Convert an SMB error into a UNIX error ... */ -int smbc_errno(struct cli_state *c) +static int smbc_errno(SMBCCTX *context, struct cli_state *c) { int ret; @@ -216,12 +204,65 @@ int smbc_errno(struct cli_state *c) ret = cli_errno_from_nt(status); DEBUG(3,("smbc errno %s -> %d\n", - nt_errstr(status), ret)); + get_nt_error_msg(status), ret)); } return ret; } +/* + * Check a server_fd. + * returns 0 if the server is in shape. Returns 1 on error + * + * Also useable outside libsmbclient to enable external cache + * to do some checks too. + */ +int smbc_check_server(SMBCCTX * context, SMBCSRV * server) +{ + if ( cli_send_keepalive(&server->cli) == False ) + return 1; + + /* connection is ok */ + return 0; +} + +/* + * Remove a server from the list server_table if it's unused. + * On success, 0 is returned. 1 is returned if the server could not be removed. + * + * Also useable outside libsmbclient + */ +int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) +{ + SMBCFILE * file; + + /* are we being fooled ? */ + if (!context || !context->_initialized || !srv) return 1; + + + /* Check all open files/directories for a relation with this server */ + for (file = context->_files; file; file=file->next) { + if (file->srv == srv) { + /* Still used */ + DEBUG(3, ("smbc_remove_usused_server: %p still used by %p.\n", + srv, file)); + return 1; + } + } + + DLIST_REMOVE(context->_servers, srv); + + cli_shutdown(&srv->cli); + + DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv)); + + context->callbacks.remove_cached_srv_fn(context, srv); + + SAFE_FREE(srv); + + return 0; +} + /* * Connect to a server, possibly on an existing connection * @@ -233,67 +274,79 @@ int smbc_errno(struct cli_state *c) * info we need, unless the username and password were passed in. */ -struct smbc_server *smbc_server(char *server, char *share, - char *workgroup, char *username, - char *password) +SMBCSRV *smbc_server(SMBCCTX *context, + char *server, char *share, + char *workgroup, char *username, + char *password) { - struct smbc_server *srv=NULL; + SMBCSRV *srv=NULL; + int auth_called = 0; struct cli_state c; struct nmb_name called, calling; char *p, *server_n = server; fstring group; pstring ipenv; struct in_addr ip; + int tried_reverse = 0; - zero_ip(&ip); + zero_ip(&ip); ZERO_STRUCT(c); - /* try to use an existing connection */ - for (srv=smbc_srvs;srv;srv=srv->next) { - if (strcmp(server,srv->server_name)==0 && - strcmp(share,srv->share_name)==0 && - strcmp(workgroup,srv->workgroup)==0 && - strcmp(username, srv->username) == 0) - return srv; - } - if (server[0] == 0) { errno = EPERM; return NULL; } - /* - * Pick up the auth info here, once we know we need to connect - * But only if we do not have a username and password ... - */ - - if (!username[0] || !password[0]) - smbc_auth_fn(server, share, workgroup, sizeof(fstring), - username, sizeof(fstring), password, sizeof(fstring)); + check_server_cache: - /* - * However, smbc_auth_fn may have picked up info relating to an - * existing connection, so try for an existing connection again ... - */ - - for (srv=smbc_srvs;srv;srv=srv->next) { - if (strcmp(server,srv->server_name)==0 && - strcmp(share,srv->share_name)==0 && - strcmp(workgroup,srv->workgroup)==0 && - strcmp(username, srv->username) == 0) - return srv; + srv = context->callbacks.get_cached_srv_fn(context, server, share, + workgroup, username); + + if (!auth_called && !srv && (!username[0] || !password[0])) { + context->callbacks.auth_fn(server, share, workgroup, sizeof(fstring), + username, sizeof(fstring), password, sizeof(fstring)); + /* + * However, smbc_auth_fn may have picked up info relating to an + * existing connection, so try for an existing connection again ... + */ + auth_called = 1; + goto check_server_cache; + } + + if (srv) { + if (context->callbacks.check_server_fn(context, srv)) { + /* + * This server is no good anymore + * Try to remove it and check for more possible servers in the cache + */ + if (context->callbacks.remove_unused_server_fn(context, srv)) { + /* + * We could not remove the server completely, remove it from the cache + * so we will not get it again. It will be removed when the last file/dir + * is closed. + */ + context->callbacks.remove_cached_srv_fn(context, srv); + } + + /* + * Maybe there are more cached connections to this server + */ + goto check_server_cache; + } + return srv; + } - make_nmb_name(&calling, my_netbios_name, 0x0); + make_nmb_name(&calling, context->netbios_name, 0x0); make_nmb_name(&called , server, 0x20); DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server)); - if ((p=strchr_m(server_n,'#')) && + if ((p=strchr(server_n,'#')) && (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) { fstrcpy(group, server_n); - p = strchr_m(group,'#'); + p = strchr(group,'#'); *p = 0; } @@ -303,21 +356,52 @@ struct smbc_server *smbc_server(char *server, char *share, again: slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n); - zero_ip(&ip); + zero_ip(&ip); /* have to open a new connection */ - if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) { - if (c.initialised) cli_shutdown(&c); + if (!cli_initialise(&c)) { errno = ENOENT; return NULL; } + c.timeout = context->timeout; + + if (!cli_connect(&c, server_n, &ip)) { + cli_shutdown(&c); + errno = ENOENT; + return NULL; + } + if (!cli_session_request(&c, &calling, &called)) { cli_shutdown(&c); if (strcmp(called.name, "*SMBSERVER")) { make_nmb_name(&called , "*SMBSERVER", 0x20); goto again; } + else { /* Try one more time, but ensure we don't loop */ + + /* Only try this if server is an IP address ... */ + + if (is_ipaddress(server) && !tried_reverse) { + fstring remote_name; + struct in_addr rem_ip; + + if (!inet_aton(server, &rem_ip)) { + DEBUG(4, ("Could not convert IP address %s to struct in_addr\n", server)); + errno = ENOENT; + return NULL; + } + + tried_reverse++; /* Yuck */ + + if (name_status_find("*", 0, 0, rem_ip, remote_name)) { + make_nmb_name(&called, remote_name, 0x20); + goto again; + } + + + } + } errno = ENOENT; return NULL; } @@ -345,50 +429,37 @@ struct smbc_server *smbc_server(char *server, char *share, if (!cli_send_tconX(&c, share, "?????", password, strlen(password)+1)) { - errno = smbc_errno(&c); + errno = smbc_errno(context, &c); cli_shutdown(&c); return NULL; } DEBUG(4,(" tconx ok\n")); - srv = (struct smbc_server *)malloc(sizeof(*srv)); + /* + * Ok, we have got a nice connection + * Let's find a free server_fd + */ + + srv = (SMBCSRV *)malloc(sizeof(*srv)); if (!srv) { errno = ENOMEM; goto failed; } ZERO_STRUCTP(srv); - srv->cli = c; - srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); - srv->server_name = strdup(server); - if (!srv->server_name) { - errno = ENOMEM; - goto failed; - } - - srv->share_name = strdup(share); - if (!srv->share_name) { - errno = ENOMEM; - goto failed; - } - - srv->workgroup = strdup(workgroup); - if (!srv->workgroup) { - errno = ENOMEM; + /* now add it to the cache (internal or external) */ + if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username)) { + DEBUG(3, (" Failed to add server to cache\n")); goto failed; } - srv->username = strdup(username); - if (!srv->username) { - errno = ENOMEM; - goto failed; - } - - DLIST_ADD(smbc_srvs, srv); + + DEBUG(2, ("Server connect ok: //%s/%s: %p\n", + server, share, srv)); return srv; @@ -396,212 +467,49 @@ struct smbc_server *smbc_server(char *server, char *share, cli_shutdown(&c); if (!srv) return NULL; - SAFE_FREE(srv->server_name); - SAFE_FREE(srv->share_name); - SAFE_FREE(srv->workgroup); - SAFE_FREE(srv->username); SAFE_FREE(srv); return NULL; } -/* - *Remove a server from the list smbc_srvs if it's unused -- Tom (tom@ninja.nl) - * - * We accept a *srv - */ -BOOL smbc_remove_unused_server(struct smbc_server * s) -{ - int p; - - /* are we being fooled ? */ - if (!s) return False; - - /* close all open files/directories on this server */ - for (p = 0; p < SMBC_MAX_FD; p++) { - if (smbc_file_table[p] && - smbc_file_table[p]->srv == s) { - /* Still used .. DARN */ - DEBUG(3, ("smbc_remove_usused_server: %x still used by %s (%d).\n", (int) s, - smbc_file_table[p]->fname, smbc_file_table[p]->smbc_fd)); - return False; - } - } - - cli_shutdown(&s->cli); - - SAFE_FREE(s->username); - SAFE_FREE(s->workgroup); - SAFE_FREE(s->server_name); - SAFE_FREE(s->share_name); - DLIST_REMOVE(smbc_srvs, s); - DEBUG(3, ("smbc_remove_usused_server: %x removed.\n", (int) s)); - SAFE_FREE(s); - return True; -} - -/* - *Initialise the library etc - * - * We accept valid values for debug from 0 to 100, - * and insist that fn must be non-null. - */ - -int smbc_init(smbc_get_auth_data_fn fn, int debug) -{ - pstring conf; - int p, pid; - char *user = NULL, *home = NULL, *pname="libsmbclient"; - - if (!fn || debug < 0 || debug > 100) { - - errno = EINVAL; - return -1; - - } - - if (smbc_initialized) { /* Don't go through this if we have already done it */ - - return 0; - - } - - smbc_initialized = 1; - smbc_auth_fn = fn; - /* smbc_debug = debug; */ - - DEBUGLEVEL = -1; - - setup_logging(pname, False); - - /* Here we would open the smb.conf file if needed ... */ - - home = getenv("HOME"); - - slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); - - load_interfaces(); /* Load the list of interfaces ... */ - - in_client = True; /* FIXME, make a param */ - - if (!lp_load(conf, True, False, False)) { - - /* - * Hmmm, what the hell do we do here ... we could not parse the - * config file ... We must return an error ... and keep info around - * about why we failed - */ - - errno = ENOENT; /* FIXME: Figure out the correct error response */ - return -1; - - } - - reopen_logs(); /* Get logging working ... */ - - /* - * FIXME: Is this the best way to get the user info? - */ - - user = getenv("USER"); - /* walk around as "guest" if no username can be found */ - if (!user) user = strdup("guest"); - pstrcpy(smbc_user, user); /* Save for use elsewhere */ - - /* - * We try to get our netbios name from the config. If that fails we fall - * back on constructing our netbios name from our hostname etc - */ - if (global_myname) { - pstrcpy(my_netbios_name, global_myname); - } - else { - /* - * Hmmm, I want to get hostname as well, but I am too lazy for the moment - */ - pid = sys_getpid(); - slprintf(my_netbios_name, 16, "smbc%s%d", user, pid); - } - DEBUG(0,("Using netbios name %s.\n", my_netbios_name)); - - /* - * Now initialize the file descriptor array and figure out what the - * max open files is, so we can return FD's that are above the max - * open file, and separated by a guard band - */ - -#if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)) - do { - struct rlimit rlp; - - if (getrlimit(RLIMIT_NOFILE, &rlp)) { - - DEBUG(0, ("smbc_init: getrlimit(1) for RLIMIT_NOFILE failed with error %s\n", strerror(errno))); - - smbc_start_fd = 1000000; - - } - else { - - smbc_start_fd = rlp.rlim_max + 10000; /* Leave a guard space of 10,000 */ - - } - } while ( 0 ); -#else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */ - - smbc_start_fd = 1000000; - -#endif - - smbc_file_table = malloc(SMBC_MAX_FD * sizeof(struct smbc_file *)); - - for (p = 0; p < SMBC_MAX_FD; p++) - smbc_file_table[p] = NULL; - - if (!smbc_file_table) - return ENOMEM; - - return 0; /* Success */ - -} - /* * Routine to open() a file ... */ -int smbc_open(const char *fname, int flags, mode_t mode) +static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, mode_t mode) { fstring server, share, user, password, workgroup; pstring path; - struct smbc_server *srv = NULL; + SMBCSRV *srv = NULL; + SMBCFILE *file = NULL; int fd; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; /* Best I can think of ... */ - return -1; + return NULL; } if (!fname) { errno = EINVAL; - return -1; + return NULL; } - smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */ + smbc_parse_path(context, fname, server, share, path, user, password); /* FIXME, check errors */ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { if (errno == EPERM) errno = EACCES; - return -1; /* smbc_server sets errno */ - + return NULL; /* smbc_server sets errno */ + } /* Hmmm, the test for a directory is suspect here ... FIXME */ @@ -612,50 +520,38 @@ int smbc_open(const char *fname, int flags, mode_t mode) } else { + + file = malloc(sizeof(SMBCFILE)); - int slot = 0; - - /* Find a free slot first */ - - while (smbc_file_table[slot]) - slot++; - - if (slot > SMBC_MAX_FD) { - - errno = ENOMEM; /* FIXME, is this best? */ - return -1; - - } - - smbc_file_table[slot] = malloc(sizeof(struct smbc_file)); - - if (!smbc_file_table[slot]) { + if (!file) { errno = ENOMEM; - return -1; + return NULL; } + ZERO_STRUCTP(file); + if ((fd = cli_open(&srv->cli, path, flags, DENY_NONE)) < 0) { /* Handle the error ... */ - SAFE_FREE(smbc_file_table[slot]); - errno = smbc_errno(&srv->cli); - return -1; + SAFE_FREE(file); + errno = smbc_errno(context, &srv->cli); + return NULL; } /* Fill in file struct */ - smbc_file_table[slot]->cli_fd = fd; - smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd; - smbc_file_table[slot]->fname = strdup(fname); - smbc_file_table[slot]->srv = srv; - smbc_file_table[slot]->offset = 0; - smbc_file_table[slot]->file = True; + file->cli_fd = fd; + file->fname = strdup(fname); + file->srv = srv; + file->offset = 0; + file->file = True; - return smbc_file_table[slot]->smbc_fd; + DLIST_ADD(context->_files, file); + return file; } @@ -664,14 +560,15 @@ int smbc_open(const char *fname, int flags, mode_t mode) if (fd == -1) { int eno = 0; - eno = smbc_errno(&srv->cli); - fd = smbc_opendir(fname); - if (fd < 0) errno = eno; - return fd; + eno = smbc_errno(context, &srv->cli); + file = context->opendir(context, fname); + if (!file) errno = eno; + return file; } - return 1; /* Success, with fd ... */ + errno = EINVAL; /* FIXME, correct errno ? */ + return NULL; } @@ -681,38 +578,37 @@ int smbc_open(const char *fname, int flags, mode_t mode) static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this */ -int smbc_creat(const char *path, mode_t mode) +static SMBCFILE *smbc_creat_ctx(SMBCCTX *context, const char *path, mode_t mode) { - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; - return -1; + return NULL; } - return smbc_open(path, creat_bits, mode); + return smbc_open_ctx(context, path, creat_bits, mode); } /* * Routine to read() a file ... */ -ssize_t smbc_read(int fd, void *buf, size_t count) +static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count) { - struct smbc_file *fe; int ret; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - DEBUG(4, ("smbc_read(%d, %d)\n", fd, (int)count)); + DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { + if (!file || !DLIST_CONTAINS(context->_files, file)) { errno = EBADF; return -1; @@ -728,25 +624,16 @@ ssize_t smbc_read(int fd, void *buf, size_t count) } - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe || !fe->file) { - - errno = EBADF; - return -1; - - } - - ret = cli_read(&fe->srv->cli, fe->cli_fd, buf, fe->offset, count); + ret = cli_read(&file->srv->cli, file->cli_fd, buf, file->offset, count); if (ret < 0) { - errno = smbc_errno(&fe->srv->cli); + errno = smbc_errno(context, &file->srv->cli); return -1; } - fe->offset += ret; + file->offset += ret; DEBUG(4, (" --> %d\n", ret)); @@ -758,19 +645,18 @@ ssize_t smbc_read(int fd, void *buf, size_t count) * Routine to write() a file ... */ -ssize_t smbc_write(int fd, void *buf, size_t count) +static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count) { int ret; - struct smbc_file *fe; - if (!smbc_initialized) { + if (!context || context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { + if (!file || !DLIST_CONTAINS(context->_files, file)) { errno = EBADF; return -1; @@ -786,25 +672,16 @@ ssize_t smbc_write(int fd, void *buf, size_t count) } - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe || !fe->file) { - - errno = EBADF; - return -1; - - } - - ret = cli_write(&fe->srv->cli, fe->cli_fd, 0, buf, fe->offset, count); + ret = cli_write(&file->srv->cli, file->cli_fd, 0, buf, file->offset, count); if (ret <= 0) { - errno = smbc_errno(&fe->srv->cli); + errno = smbc_errno(context, &file->srv->cli); return -1; } - fe->offset += ret; + file->offset += ret; return ret; /* Success, 0 bytes of data ... */ } @@ -813,75 +690,123 @@ ssize_t smbc_write(int fd, void *buf, size_t count) * Routine to close() a file ... */ -int smbc_close(int fd) +static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) { - struct smbc_file *fe; - struct smbc_server *srv; + SMBCSRV *srv; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { + if (!file || !DLIST_CONTAINS(context->_files, file)) { errno = EBADF; return -1; } - fe = smbc_file_table[fd - smbc_start_fd]; + /* IS a dir ... */ + if (!file->file) { + + return context->closedir(context, file); + + } - if (!fe) { + if (!cli_close(&file->srv->cli, file->cli_fd)) { + + DEBUG(3, ("cli_close failed on %s. purging server.\n", + file->fname)); + /* Deallocate slot and remove the server + * from the server cache if unused */ + errno = smbc_errno(context, &file->srv->cli); + srv = file->srv; + DLIST_REMOVE(context->_files, file); + SAFE_FREE(file->fname); + SAFE_FREE(file); + context->callbacks.remove_unused_server_fn(context, srv); - errno = EBADF; return -1; } - if (!fe->file) { + if (!file->file) { - return smbc_closedir(fd); + return context->closedir(context, file); } - if (!cli_close(&fe->srv->cli, fe->cli_fd)) { - - DEBUG(3, ("cli_close failed on %s (%d). purging server.\n", - fe->fname, fe->smbc_fd)); + if (!cli_close(&file->srv->cli, file->cli_fd)) { + DEBUG(3, ("cli_close failed on %s. purging server.\n", + file->fname)); /* Deallocate slot and remove the server * from the server cache if unused */ - errno = smbc_errno(&fe->srv->cli); - srv = fe->srv; - SAFE_FREE(fe->fname); - SAFE_FREE(fe); - smbc_file_table[fd - smbc_start_fd] = NULL; - smbc_remove_unused_server(srv); + errno = smbc_errno(context, &file->srv->cli); + srv = file->srv; + DLIST_REMOVE(context->_files, file); + SAFE_FREE(file->fname); + SAFE_FREE(file); + context->callbacks.remove_unused_server_fn(context, srv); return -1; - } - SAFE_FREE(fe->fname); - SAFE_FREE(fe); - smbc_file_table[fd - smbc_start_fd] = NULL; + DLIST_REMOVE(context->_files, file); + SAFE_FREE(file->fname); + SAFE_FREE(file); return 0; } +/* + * Get info from an SMB server on a file. Use a qpathinfo call first + * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo + */ +static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, + uint16 *mode, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time, + SMB_INO_T *ino) +{ + + if (!context || !context->_initialized) { + + errno = EINVAL; + return -1; + + } + + DEBUG(4,("smbc_getatr: sending qpathinfo\n")); + + if (!srv->no_pathinfo2 && + cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL, + size, mode, ino)) return True; + + /* if this is NT then don't bother with the getatr */ + if (srv->cli.capabilities & CAP_NT_SMBS) return False; + + if (cli_getatr(&srv->cli, path, mode, size, m_time)) { + a_time = c_time = m_time; + srv->no_pathinfo2 = True; + return True; + } + + return False; + +} + /* * Routine to unlink() a file */ -int smbc_unlink(const char *fname) +static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) { fstring server, share, user, password, workgroup; pstring path; - struct smbc_server *srv = NULL; + SMBCSRV *srv = NULL; - if (!smbc_initialized) { + if (!context || context->_initialized) { errno = EINVAL; /* Best I can think of ... */ return -1; @@ -895,13 +820,13 @@ int smbc_unlink(const char *fname) } - smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */ + smbc_parse_path(context, fname, server, share, path, user, password); /* FIXME, check errors */ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { @@ -911,23 +836,23 @@ int smbc_unlink(const char *fname) /* if (strncmp(srv->cli.dev, "LPT", 3) == 0) { - int job = smbc_stat_printjob(srv, path, NULL, NULL); - if (job == -1) { + int job = smbc_stat_printjob(srv, path, NULL, NULL); + if (job == -1) { - return -1; + return -1; - } - if ((err = cli_printjob_del(&srv->cli, job)) != 0) { + } + if ((err = cli_printjob_del(&srv->cli, job)) != 0) { - return -1; + return -1; - } - } else */ + } + } else */ if (!cli_unlink(&srv->cli, path)) { - errno = smbc_errno(&srv->cli); + errno = smbc_errno(context, &srv->cli); if (errno == EACCES) { /* Check if the file is a directory */ @@ -937,12 +862,12 @@ int smbc_unlink(const char *fname) time_t m_time = 0, a_time = 0, c_time = 0; SMB_INO_T ino = 0; - if (!smbc_getatr(srv, path, &mode, &size, + if (!smbc_getatr(context, srv, path, &mode, &size, &c_time, &a_time, &m_time, &ino)) { /* Hmmm, bad error ... What? */ - errno = smbc_errno(&srv->cli); + errno = smbc_errno(context, &srv->cli); return -1; } @@ -968,35 +893,37 @@ int smbc_unlink(const char *fname) * Routine to rename() a file */ -int smbc_rename(const char *oname, const char *nname) +static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, + SMBCCTX *ncontext, const char *nname) { fstring server1, share1, server2, share2, user1, user2, password1, password2, workgroup; pstring path1, path2; - struct smbc_server *srv = NULL; + SMBCSRV *srv = NULL; - if (!smbc_initialized) { + if (!ocontext || !ncontext || + !ocontext->_initialized || !ncontext->_initialized) { errno = EINVAL; /* Best I can think of ... */ return -1; } - + if (!oname || !nname) { errno = EINVAL; return -1; } - + DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); - smbc_parse_path(oname, server1, share1, path1, user1, password1); + smbc_parse_path(ocontext, oname, server1, share1, path1, user1, password1); - if (user1[0] == (char)0) pstrcpy(user1, smbc_user); + if (user1[0] == (char)0) pstrcpy(user1, ocontext->user); - smbc_parse_path(nname, server2, share2, path2, user2, password2); + smbc_parse_path(ncontext, nname, server2, share2, path2, user2, password2); - if (user2[0] == (char)0) pstrcpy(user2, smbc_user); + if (user2[0] == (char)0) pstrcpy(user2, ncontext->user); if (strcmp(server1, server2) || strcmp(share1, share2) || strcmp(user1, user2)) { @@ -1008,9 +935,9 @@ int smbc_rename(const char *oname, const char *nname) } - pstrcpy(workgroup, lp_workgroup()); - - srv = smbc_server(server1, share1, workgroup, user1, password1); + pstrcpy(workgroup, ocontext->workgroup); + /* HELP !!! Which workgroup should I use ? Or are they always the same -- Tom */ + srv = smbc_server(ocontext, server1, share1, workgroup, user1, password1); if (!srv) { return -1; @@ -1018,7 +945,7 @@ int smbc_rename(const char *oname, const char *nname) } if (!cli_rename(&srv->cli, path1, path2)) { - int eno = smbc_errno(&srv->cli); + int eno = smbc_errno(ocontext, &srv->cli); if (eno != EEXIST || !cli_unlink(&srv->cli, path2) || @@ -1038,35 +965,25 @@ int smbc_rename(const char *oname, const char *nname) * A routine to lseek() a file */ -off_t smbc_lseek(int fd, off_t offset, int whence) +static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence) { - struct smbc_file *fe; size_t size; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; - - } - - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - - errno = EBADF; - return -1; - + } - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { + if (!file || !DLIST_CONTAINS(context->_files, file)) { errno = EBADF; return -1; } - if (!fe->file) { + if (!file->file) { errno = EINVAL; return -1; /* Can't lseek a dir ... */ @@ -1075,23 +992,23 @@ off_t smbc_lseek(int fd, off_t offset, int whence) switch (whence) { case SEEK_SET: - fe->offset = offset; + file->offset = offset; break; case SEEK_CUR: - fe->offset += offset; + file->offset += offset; break; case SEEK_END: - if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL, + if (!cli_qfileinfo(&file->srv->cli, file->cli_fd, NULL, &size, NULL, NULL, NULL, NULL, NULL) && - !cli_getattrE(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL, + !cli_getattrE(&file->srv->cli, file->cli_fd, NULL, &size, NULL, NULL, NULL)) { errno = EINVAL; return -1; } - fe->offset = size + offset; + file->offset = size + offset; break; default: @@ -1100,7 +1017,7 @@ off_t smbc_lseek(int fd, off_t offset, int whence) } - return fe->offset; + return file->offset; } @@ -1109,9 +1026,16 @@ off_t smbc_lseek(int fd, off_t offset, int whence) */ static -ino_t smbc_inode(const char *name) +ino_t smbc_inode(SMBCCTX *context, const char *name) { + if (!context || !context->_initialized) { + + errno = EINVAL; + return -1; + + } + if (!*name) return 2; /* FIXME, why 2 ??? */ return (ino_t)str_checksum(name); @@ -1123,9 +1047,9 @@ ino_t smbc_inode(const char *name) */ static -int smbc_setup_stat(struct stat *st, char *fname, size_t size, int mode) +int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname, size_t size, int mode) { - + st->st_mode = 0; if (IS_DOS_DIR(mode)) { @@ -1152,55 +1076,20 @@ int smbc_setup_stat(struct stat *st, char *fname, size_t size, int mode) } if (st->st_ino == 0) { - st->st_ino = smbc_inode(fname); + st->st_ino = smbc_inode(context, fname); } - + return True; /* FIXME: Is this needed ? */ } -/* - * Get info from an SMB server on a file. Use a qpathinfo call first - * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo - */ - -static BOOL smbc_getatr(struct smbc_server *srv, char *path, - uint16 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time, - SMB_INO_T *ino) -{ - - if (!smbc_initialized) { - - errno = EINVAL; - return -1; - - } - - DEBUG(4,("smbc_getatr: sending qpathinfo\n")); - - if (!srv->no_pathinfo2 && - cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL, - size, mode, ino)) return True; - - /* if this is NT then don't bother with the getatr */ - if (srv->cli.capabilities & CAP_NT_SMBS) return False; - - if (cli_getatr(&srv->cli, path, mode, size, m_time)) { - a_time = c_time = m_time; - srv->no_pathinfo2 = True; - return True; - } - return False; -} - /* * Routine to stat a file given a name */ -int smbc_stat(const char *fname, struct stat *st) +static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) { - struct smbc_server *srv; + SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; time_t m_time = 0, a_time = 0, c_time = 0; @@ -1208,11 +1097,11 @@ int smbc_stat(const char *fname, struct stat *st) uint16 mode = 0; SMB_INO_T ino = 0; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; /* Best I can think of ... */ return -1; - + } if (!fname) { @@ -1224,13 +1113,13 @@ int smbc_stat(const char *fname, struct stat *st) DEBUG(4, ("smbc_stat(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { @@ -1244,9 +1133,9 @@ int smbc_stat(const char *fname, struct stat *st) } else if (strncmp(srv->cli.dev, "LPT", 3) == 0) { - + if (strcmp(path, "\\") == 0) { - + mode = aDIR | aRONLY; } @@ -1259,19 +1148,17 @@ int smbc_stat(const char *fname, struct stat *st) } else { */ - if (!smbc_getatr(srv, path, &mode, &size, + if (!smbc_getatr(context, srv, path, &mode, &size, &c_time, &a_time, &m_time, &ino)) { - errno = smbc_errno(&srv->cli); + errno = smbc_errno(context, &srv->cli); return -1; - + } - /* } */ - st->st_ino = ino; - smbc_setup_stat(st, path, size, mode); + smbc_setup_stat(context, st, path, size, mode); st->st_atime = a_time; st->st_ctime = c_time; @@ -1286,46 +1173,36 @@ int smbc_stat(const char *fname, struct stat *st) * Routine to stat a file given an fd */ -int smbc_fstat(int fd, struct stat *st) +static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) { - struct smbc_file *fe; time_t c_time, a_time, m_time; size_t size; uint16 mode; SMB_INO_T ino = 0; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - - errno = EBADF; - return -1; - - } - - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { + if (!file || !DLIST_CONTAINS(context->_files, file)) { errno = EBADF; return -1; } - if (!fe->file) { + if (!file->file) { - return smbc_fstatdir(fd, st); + return context->fstatdir(context, file, st); } - if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd, + if (!cli_qfileinfo(&file->srv->cli, file->cli_fd, &mode, &size, &c_time, &a_time, &m_time, NULL, &ino) && - !cli_getattrE(&fe->srv->cli, fe->cli_fd, + !cli_getattrE(&file->srv->cli, file->cli_fd, &mode, &size, &c_time, &a_time, &m_time)) { errno = EINVAL; @@ -1335,12 +1212,12 @@ int smbc_fstat(int fd, struct stat *st) st->st_ino = ino; - smbc_setup_stat(st, fe->fname, size, mode); + smbc_setup_stat(context, st, file->fname, size, mode); st->st_atime = a_time; st->st_ctime = c_time; st->st_mtime = m_time; - st->st_dev = fe->srv->dev; + st->st_dev = file->srv->dev; return 0; @@ -1360,7 +1237,7 @@ int smbc_fstat(int fd, struct stat *st) * smb:///share which should list files on share */ -static void smbc_remove_dir(struct smbc_file *dir) +static void smbc_remove_dir(SMBCFILE *dir) { struct smbc_dir_list *d,*f; @@ -1378,7 +1255,7 @@ static void smbc_remove_dir(struct smbc_file *dir) } -static int add_dirent(struct smbc_file *dir, const char *name, const char *comment, uint32 type) +static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint32 type) { struct smbc_dirent *dirent; int size; @@ -1401,6 +1278,11 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme } + ZERO_STRUCTP(dirent); + + ZERO_STRUCTP(dirent); + + if (dir->dir_list == NULL) { dir->dir_list = malloc(sizeof(struct smbc_dir_list)); @@ -1411,6 +1293,7 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme return -1; } + ZERO_STRUCTP(dir->dir_list); dir->dir_end = dir->dir_next = dir->dir_list; @@ -1418,14 +1301,15 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme else { dir->dir_end->next = malloc(sizeof(struct smbc_dir_list)); - - if (!dir->dir_end) { - + + if (!dir->dir_end->next) { + SAFE_FREE(dirent); dir->dir_error = ENOMEM; return -1; } + ZERO_STRUCTP(dir->dir_end->next); dir->dir_end = dir->dir_end->next; @@ -1433,7 +1317,7 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme dir->dir_end->next = NULL; dir->dir_end->dirent = dirent; - + dirent->smbc_type = type; dirent->namelen = (name?strlen(name):0); dirent->commentlen = (comment?strlen(comment):0); @@ -1451,13 +1335,13 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme static void list_fn(const char *name, uint32 type, const char *comment, void *state) { - struct smbc_file *dir = (struct smbc_file *)state; + SMBCFILE *dir = (SMBCFILE *)state; int dirent_type; /* We need to process the type a little ... */ if (dir->dir_type == SMBC_FILE_SHARE) { - + switch (type) { case 0: /* Directory tree */ dirent_type = SMBC_FILE_SHARE; @@ -1479,6 +1363,7 @@ list_fn(const char *name, uint32 type, const char *comment, void *state) dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */ break; } + ZERO_STRUCTP(dir->dir_list); } else dirent_type = dir->dir_type; @@ -1496,113 +1381,103 @@ static void dir_list_fn(file_info *finfo, const char *mask, void *state) { - if (add_dirent((struct smbc_file *)state, finfo->name, "", + if (add_dirent((SMBCFILE *)state, finfo->name, "", (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { /* Handle an error ... */ + /* FIXME: Add some code ... */ } } -int smbc_opendir(const char *fname) +static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) { fstring server, share, user, password, workgroup; pstring path; - struct smbc_server *srv = NULL; + SMBCSRV *srv = NULL; + SMBCFILE *dir = NULL; struct in_addr rem_ip; int slot = 0; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; - return -1; + return NULL; } if (!fname) { errno = EINVAL; - return -1; + return NULL; } - if (smbc_parse_path(fname, server, share, path, user, password)) { + if (smbc_parse_path(context, fname, server, share, path, user, password)) { errno = EINVAL; - return -1; + return NULL; } - if (user[0] == (char)0) pstrcpy(user, smbc_user); - - pstrcpy(workgroup, lp_workgroup()); - - /* Get a file entry ... */ - - slot = 0; + if (user[0] == (char)0) pstrcpy(user, context->user); - while (smbc_file_table[slot]) - slot++; - - if (slot > SMBC_MAX_FD) { - - errno = ENOMEM; - return -1; /* FIXME, ... move into a func */ - - } + pstrcpy(workgroup, context->workgroup); - smbc_file_table[slot] = malloc(sizeof(struct smbc_file)); + dir = malloc(sizeof(*dir)); - if (!smbc_file_table[slot]) { + if (!dir) { errno = ENOMEM; - return -1; + return NULL; } - smbc_file_table[slot]->cli_fd = 0; - smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd; - smbc_file_table[slot]->fname = strdup(fname); - smbc_file_table[slot]->srv = NULL; - smbc_file_table[slot]->offset = 0; - smbc_file_table[slot]->file = False; - smbc_file_table[slot]->dir_list = - smbc_file_table[slot]->dir_next = - smbc_file_table[slot]->dir_end = NULL; + ZERO_STRUCTP(dir); + + dir->cli_fd = 0; + dir->fname = strdup(fname); + dir->srv = NULL; + dir->offset = 0; + dir->file = False; + dir->dir_list = dir->dir_next = dir->dir_end = NULL; if (server[0] == (char)0) { if (share[0] != (char)0 || path[0] != (char)0) { errno = EINVAL; - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } /* We have server and share and path empty ... so list the workgroups */ + /* first try to get the LMB for our workgroup, and if that fails, */ + /* try the DMB */ - if (!resolve_name(lp_workgroup(), &rem_ip, 0x1d)) { + if (!(resolve_name(context->workgroup, &rem_ip, 0x1d) || + resolve_name(context->workgroup, &rem_ip, 0x1b))) { errno = EINVAL; /* Something wrong with smb.conf? */ - return -1; + return NULL; } - smbc_file_table[slot]->dir_type = SMBC_WORKGROUP; + dir->dir_type = SMBC_WORKGROUP; /* find the name of the server ... */ if (!name_status_find("*", 0, 0, rem_ip, server)) { - DEBUG(0, ("Could not get the name of local master browser for server %s\n", server)); + DEBUG(0,("Could not get the name of local/domain master browser for server %s\n", server)); errno = EINVAL; - return -1; + return NULL; } @@ -1610,31 +1485,34 @@ int smbc_opendir(const char *fname) * Get a connection to IPC$ on the server if we do not already have one */ - srv = smbc_server(server, "IPC$", workgroup, user, password); + srv = smbc_server(context, server, "IPC$", workgroup, user, password); if (!srv) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + + return NULL; } + ZERO_STRUCTP(dir->dir_end); - smbc_file_table[slot]->srv = srv; + dir->srv = srv; /* Now, list the stuff ... */ if (!cli_NetServerEnum(&srv->cli, workgroup, 0x80000000, list_fn, - (void *)smbc_file_table[slot])) { + (void *)dir)) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } errno = cli_errno(&srv->cli); - return -1; + + return NULL; } } @@ -1645,22 +1523,23 @@ int smbc_opendir(const char *fname) if (path[0] != (char)0) { /* Should not have empty share with path */ errno = EINVAL; - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } - /* Check to see if <1D> translates, or <20> translates */ + /* Check to see if <1D>, <1B>, or <20> translates */ /* However, we check to see if is an IP address first */ if (!is_ipaddress(server) && /* Not an IP addr so check next */ - resolve_name(server, &rem_ip, 0x1d)) { /* Found LMB */ + (resolve_name(server, &rem_ip, 0x1d) || /* Found LMB */ + resolve_name(server, &rem_ip, 0x1b) )) { /* Found DMB */ pstring buserver; - smbc_file_table[slot]->dir_type = SMBC_SERVER; + dir->dir_type = SMBC_SERVER; /* * Get the backup list ... @@ -1669,9 +1548,9 @@ int smbc_opendir(const char *fname) if (!name_status_find("*", 0, 0, rem_ip, buserver)) { - DEBUG(0, ("Could not get name of local master browser %s\n", server)); + DEBUG(0, ("Could not get name of local/domain master browser for server %s\n", server)); errno = EPERM; /* FIXME, is this correct */ - return -1; + return NULL; } @@ -1679,32 +1558,32 @@ int smbc_opendir(const char *fname) * Get a connection to IPC$ on the server if we do not already have one */ - srv = smbc_server(buserver, "IPC$", workgroup, user, password); + srv = smbc_server(context, buserver, "IPC$", workgroup, user, password); if (!srv) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } - smbc_file_table[slot]->srv = srv; + dir->srv = srv; /* Now, list the servers ... */ if (!cli_NetServerEnum(&srv->cli, server, 0x0000FFFE, list_fn, - (void *)smbc_file_table[slot])) { + (void *)dir)) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } errno = cli_errno(&srv->cli); - return -1; - + return NULL; + } } @@ -1714,33 +1593,33 @@ int smbc_opendir(const char *fname) /* Now, list the shares ... */ - smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE; + dir->dir_type = SMBC_FILE_SHARE; - srv = smbc_server(server, "IPC$", workgroup, user, password); + srv = smbc_server(context, server, "IPC$", workgroup, user, password); if (!srv) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } - smbc_file_table[slot]->srv = srv; + dir->srv = srv; /* Now, list the servers ... */ if (cli_RNetShareEnum(&srv->cli, list_fn, - (void *)smbc_file_table[slot]) < 0) { + (void *)dir) < 0) { errno = cli_errno(&srv->cli); - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } @@ -1748,11 +1627,11 @@ int smbc_opendir(const char *fname) else { errno = ENODEV; /* Neither the workgroup nor server exists */ - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } @@ -1763,42 +1642,43 @@ int smbc_opendir(const char *fname) /* Well, we connect to the server and list the directory */ - smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE; + dir->dir_type = SMBC_FILE_SHARE; - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } - smbc_file_table[slot]->srv = srv; + dir->srv = srv; /* Now, list the files ... */ pstrcat(path, "\\*"); if (cli_list(&srv->cli, path, aDIR | aSYSTEM | aHIDDEN, dir_list_fn, - (void *)smbc_file_table[slot]) < 0) { + (void *)dir) < 0) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - errno = smbc_errno(&srv->cli); - return -1; + errno = smbc_errno(context, &srv->cli); + return NULL; } } } - return smbc_file_table[slot]->smbc_fd; + DLIST_ADD(context->_files, dir); + return dir; } @@ -1806,44 +1686,34 @@ int smbc_opendir(const char *fname) * Routine to close a directory */ -int smbc_closedir(int fd) +static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir) { - struct smbc_file *fe; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { + if (!dir || !DLIST_CONTAINS(context->_files, dir)) { errno = EBADF; return -1; - + } - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { + smbc_remove_dir(dir); /* Clean it up */ - errno = EBADF; - return -1; - - } - - smbc_remove_dir(fe); /* Clean it up */ + DLIST_REMOVE(context->_files, dir); - if (fe) { + if (dir) { - SAFE_FREE(fe->fname); - SAFE_FREE(fe); /* Free the space too */ + SAFE_FREE(dir->fname); + SAFE_FREE(dir); /* Free the space too */ } - smbc_file_table[fd - smbc_start_fd] = NULL; - return 0; } @@ -1852,50 +1722,38 @@ int smbc_closedir(int fd) * Routine to get a directory entry */ -static char smbc_local_dirent[512]; /* Make big enough */ - -struct smbc_dirent *smbc_readdir(unsigned int fd) +struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir) { - struct smbc_file *fe; struct smbc_dirent *dirp, *dirent; /* Check that all is ok first ... */ - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return NULL; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - - errno = EBADF; - return NULL; - - } - - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { + if (!dir || !DLIST_CONTAINS(context->_files, dir)) { errno = EBADF; return NULL; } - if (fe->file != False) { /* FIXME, should be dir, perhaps */ + if (dir->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; return NULL; } - if (!fe->dir_next) + if (!dir->dir_next) return NULL; else { - dirent = fe->dir_next->dirent; + dirent = dir->dir_next->dirent; if (!dirent) { @@ -1906,15 +1764,12 @@ struct smbc_dirent *smbc_readdir(unsigned int fd) /* Hmmm, do I even need to copy it? */ - memcpy(smbc_local_dirent, dirent, dirent->dirlen); /* Copy the dirent */ - - dirp = (struct smbc_dirent *)smbc_local_dirent; - + memcpy(context->_dirent, dirent, dirent->dirlen); /* Copy the dirent */ + dirp = (struct smbc_dirent *)context->_dirent; dirp->comment = (char *)(&dirp->name + dirent->namelen + 1); - - fe->dir_next = fe->dir_next->next; + dir->dir_next = dir->dir_next->next; - return (struct smbc_dirent *)smbc_local_dirent; + return (struct smbc_dirent *)context->_dirent; } } @@ -1923,39 +1778,29 @@ struct smbc_dirent *smbc_readdir(unsigned int fd) * Routine to get directory entries */ -int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) +static int smbc_getdents_ctx(SMBCCTX *context, SMBCFILE *dir, struct smbc_dirent *dirp, int count) { - struct smbc_file *fe; - struct smbc_dir_list *dir; + struct smbc_dir_list *dirlist; int rem = count, reqd; char *ndir = (char *)dirp; /* Check that all is ok first ... */ - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - - errno = EBADF; - return -1; - - } - - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { + if (!dir || !DLIST_CONTAINS(context->_files, dir)) { errno = EBADF; return -1; - + } - if (fe->file != False) { /* FIXME, should be dir, perhaps */ + if (dir->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; return -1; @@ -1968,18 +1813,18 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) * send a request to the server to get the info. */ - while ((dir = fe->dir_next)) { + while ((dirlist = dir->dir_next)) { struct smbc_dirent *dirent; - if (!dir->dirent) { + if (!dirlist->dirent) { errno = ENOENT; /* Bad error */ return -1; } - if (rem < (reqd = (sizeof(struct smbc_dirent) + dir->dirent->namelen + - dir->dirent->commentlen + 1))) { + if (rem < (reqd = (sizeof(struct smbc_dirent) + dirlist->dirent->namelen + + dirlist->dirent->commentlen + 1))) { if (rem < count) { /* We managed to copy something */ @@ -1996,7 +1841,7 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) } - dirent = dir->dirent; + dirent = dirlist->dirent; memcpy(ndir, dirent, reqd); /* Copy the data in ... */ @@ -2007,7 +1852,7 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) rem -= reqd; - fe->dir_next = dir = dir -> next; + dir->dir_next = dirlist = dirlist -> next; } if (rem == count) @@ -2021,13 +1866,13 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) * Routine to create a directory ... */ -int smbc_mkdir(const char *fname, mode_t mode) +static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode) { - struct smbc_server *srv; + SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; @@ -2043,13 +1888,13 @@ int smbc_mkdir(const char *fname, mode_t mode) DEBUG(4, ("smbc_mkdir(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { @@ -2080,7 +1925,7 @@ int smbc_mkdir(const char *fname, mode_t mode) if (!cli_mkdir(&srv->cli, path)) { - errno = smbc_errno(&srv->cli); + errno = smbc_errno(context, &srv->cli); return -1; } @@ -2107,13 +1952,13 @@ static void rmdir_list_fn(file_info *finfo, const char *mask, void *state) * Routine to remove a directory */ -int smbc_rmdir(const char *fname) +static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) { - struct smbc_server *srv; + SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; @@ -2129,13 +1974,13 @@ int smbc_rmdir(const char *fname) DEBUG(4, ("smbc_rmdir(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { @@ -2160,13 +2005,13 @@ int smbc_rmdir(const char *fname) mode = aRONLY; smbc_stat_printjob(srv, path, &size, &m_time); c_time = a_time = m_time; - + } else { */ if (!cli_rmdir(&srv->cli, path)) { - errno = smbc_errno(&srv->cli); + errno = smbc_errno(context, &srv->cli); if (errno == EACCES) { /* Check if the dir empty or not */ @@ -2183,7 +2028,7 @@ int smbc_rmdir(const char *fname) /* Fix errno to ignore latest error ... */ DEBUG(5, ("smbc_rmdir: cli_list returned an error: %d\n", - smbc_errno(&srv->cli))); + smbc_errno(context, &srv->cli))); errno = EACCES; } @@ -2207,41 +2052,31 @@ int smbc_rmdir(const char *fname) * Routine to return the current directory position */ -off_t smbc_telldir(int fd) +static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir) { - struct smbc_file *fe; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - - errno = EBADF; - return -1; - - } - - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { + if (!dir || !DLIST_CONTAINS(context->_files, dir)) { errno = EBADF; return -1; } - if (fe->file != False) { /* FIXME, should be dir, perhaps */ + if (dir->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; return -1; } - return (off_t) fe->dir_next; + return (off_t) dir->dir_next; } @@ -2279,36 +2114,19 @@ struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list, * Routine to seek on a directory */ -int smbc_lseekdir(int fd, off_t offset) +static int smbc_lseekdir_ctx(SMBCCTX *context, SMBCFILE *dir, off_t offset) { - struct smbc_file *fe; struct smbc_dirent *dirent = (struct smbc_dirent *)offset; struct smbc_dir_list *list_ent = NULL; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - - errno = EBADF; - return -1; - - } - - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { - - errno = EBADF; - return -1; - - } - - if (fe->file != False) { /* FIXME, should be dir, perhaps */ + if (dir->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; return -1; @@ -2319,7 +2137,7 @@ int smbc_lseekdir(int fd, off_t offset) if (dirent == NULL) { /* Seek to the begining of the list */ - fe->dir_next = fe->dir_list; + dir->dir_next = dir->dir_list; return 0; } @@ -2327,14 +2145,14 @@ int smbc_lseekdir(int fd, off_t offset) /* Now, run down the list and make sure that the entry is OK */ /* This may need to be changed if we change the format of the list */ - if ((list_ent = smbc_check_dir_ent(fe->dir_list, dirent)) == NULL) { + if ((list_ent = smbc_check_dir_ent(dir->dir_list, dirent)) == NULL) { errno = EINVAL; /* Bad entry */ return -1; } - fe->dir_next = list_ent; + dir->dir_next = list_ent; return 0; @@ -2344,10 +2162,10 @@ int smbc_lseekdir(int fd, off_t offset) * Routine to fstat a dir */ -static int smbc_fstatdir(int fd, struct stat *st) +static int smbc_fstatdir_ctx(SMBCCTX *context, SMBCFILE *dir, struct stat *st) { - if (!smbc_initialized) { + if (context || !context->_initialized) { errno = EINVAL; return -1; @@ -2360,6 +2178,39 @@ static int smbc_fstatdir(int fd, struct stat *st) } +/* + * Open a print file to be written to by other calls + */ + +static SMBCFILE *smbc_open_print_job_ctx(SMBCCTX *context, const char *fname) +{ + fstring server, share, user, password; + pstring path; + + if (!context || context->_initialized) { + + errno = EINVAL; + return NULL; + + } + + if (!fname) { + + errno = EINVAL; + return NULL; + + } + + DEBUG(4, ("smbc_open_print_job_ctx(%s)\n", fname)); + + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + + /* What if the path is empty, or the file exists? */ + + return context->open(context, fname, O_WRONLY, 666); + +} + /* * Routine to print a file on a remote server ... * @@ -2367,12 +2218,14 @@ static int smbc_fstatdir(int fd, struct stat *st) * copy it to a print file on the share specified by printq. */ -int smbc_print_file(const char *fname, const char *printq) +static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_print, const char *printq) { - int fid1, fid2, bytes, saverr, tot_bytes = 0; + SMBCFILE *fid1, *fid2; + int bytes, saverr, tot_bytes = 0; char buf[4096]; - if (!smbc_initialized) { + if (!c_file || !c_file->_initialized || !c_print || + !c_print->_initialized) { errno = EINVAL; return -1; @@ -2388,33 +2241,33 @@ int smbc_print_file(const char *fname, const char *printq) /* Try to open the file for reading ... */ - if ((fid1 = smbc_open(fname, O_RDONLY, 0666)) < 0) { - + if ((fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) { + DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); return -1; /* smbc_open sets errno */ - + } /* Now, try to open the printer file for writing */ - if ((fid2 = smbc_open_print_job(printq)) < 0) { + if ((fid2 = c_print->open_print_job(c_print, printq)) < 0) { saverr = errno; /* Save errno */ - smbc_close(fid1); + c_file->close(c_file, fid1); errno = saverr; return -1; } - while ((bytes = smbc_read(fid1, buf, sizeof(buf))) > 0) { + while ((bytes = c_file->read(c_file, fid1, buf, sizeof(buf))) > 0) { tot_bytes += bytes; - if ((smbc_write(fid2, buf, bytes)) < 0) { + if ((c_print->write(c_print, fid2, buf, bytes)) < 0) { saverr = errno; - smbc_close(fid1); - smbc_close(fid2); + c_file->close(c_file, fid1); + c_print->close(c_print, fid2); errno = saverr; } @@ -2423,8 +2276,8 @@ int smbc_print_file(const char *fname, const char *printq) saverr = errno; - smbc_close(fid1); /* We have to close these anyway */ - smbc_close(fid2); + c_file->close(c_file, fid1); /* We have to close these anyway */ + c_print->close(c_print, fid2); if (bytes < 0) { @@ -2438,15 +2291,16 @@ int smbc_print_file(const char *fname, const char *printq) } /* - * Open a print file to be written to by other calls + * Routine to list print jobs on a printer share ... */ -int smbc_open_print_job(const char *fname) +static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, void (*fn)(struct print_job_info *)) { - fstring server, share, user, password; + SMBCSRV *srv; + fstring server, share, user, password, workgroup; pstring path; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; @@ -2454,33 +2308,51 @@ int smbc_open_print_job(const char *fname) } if (!fname) { - + errno = EINVAL; return -1; } - DEBUG(4, ("smbc_open_print_job(%s)\n", fname)); + DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - /* What if the path is empty, or the file exists? */ + if (user[0] == (char)0) pstrcpy(user, context->user); + + pstrcpy(workgroup, context->workgroup); + + srv = smbc_server(context, server, share, workgroup, user, password); + + if (!srv) { + + return -1; /* errno set by smbc_server */ + + } + + if (cli_print_queue(&srv->cli, fn) < 0) { + + errno = smbc_errno(context, &srv->cli); + return -1; - return smbc_open(fname, O_WRONLY, 666); + } + + return 0; } /* - * Routine to list print jobs on a printer share ... + * Delete a print job from a remote printer share */ -int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) +static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id) { - struct smbc_server *srv; + SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; + int err; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; @@ -2494,15 +2366,15 @@ int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) } - DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); + DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { @@ -2510,9 +2382,12 @@ int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) } - if (cli_print_queue(&srv->cli, fn) < 0) { + if ((err = cli_printjob_del(&srv->cli, id)) != 0) { - errno = smbc_errno(&srv->cli); + if (err < 0) + errno = smbc_errno(context, &srv->cli); + else if (err == ERRnosuchprintjob) + errno = EINVAL; return -1; } @@ -2522,58 +2397,263 @@ int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) } /* - * Delete a print job from a remote printer share + * Get a new empty handle to fill in with your own info */ +SMBCCTX * smbc_new_context(void) +{ + SMBCCTX * context; + + context = malloc(sizeof(*context)); + if (!context) { + errno = ENOMEM; + return NULL; + } + + ZERO_STRUCTP(context); + + /* ADD REASONABLE DEFAULTS */ + context->debug = 0; + context->timeout = 20000; /* 20 seconds */ + + context->open = smbc_open_ctx; + context->creat = smbc_creat_ctx; + context->read = smbc_read_ctx; + context->write = smbc_write_ctx; + context->close = smbc_close_ctx; + context->unlink = smbc_unlink_ctx; + context->rename = smbc_rename_ctx; + context->lseek = smbc_lseek_ctx; + context->stat = smbc_stat_ctx; + context->fstat = smbc_fstat_ctx; + context->opendir = smbc_opendir_ctx; + context->closedir = smbc_closedir_ctx; + context->readdir = smbc_readdir_ctx; + context->getdents = smbc_getdents_ctx; + context->mkdir = smbc_mkdir_ctx; + context->rmdir = smbc_rmdir_ctx; + context->telldir = smbc_telldir_ctx; + context->lseekdir = smbc_lseekdir_ctx; + context->fstatdir = smbc_fstatdir_ctx; + context->open_print_job = smbc_open_print_job_ctx; + context->print_file = smbc_print_file_ctx; + context->list_print_jobs = smbc_list_print_jobs_ctx; + context->unlink_print_job = smbc_unlink_print_job_ctx; + + context->callbacks.check_server_fn = smbc_check_server; + context->callbacks.remove_unused_server_fn = smbc_remove_unused_server; + + smbc_default_cache_functions(context); + + return context; +} -int smbc_unlink_print_job(const char *fname, int id) +/* + * Free a context + * + * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed + * and thus you'll be leaking memory if not handled properly. + * + */ +int smbc_free_context(SMBCCTX * context, int shutdown_ctx) { - struct smbc_server *srv; - fstring server, share, user, password, workgroup; - pstring path; - int err; + if (!context) { + errno = EBADF; + return 1; + } + + if (shutdown_ctx) { + SMBCFILE * f; + DEBUG(1,("Performing aggressive shutdown.\n")); + + f = context->_files; + while (f) { + context->close(context, f); + f = f->next; + } + context->_files = NULL; + + /* First try to remove the servers the nice way. */ + if (context->callbacks.purge_cached_fn(context)) { + SMBCSRV * s; + DEBUG(1, ("Could not purge all servers, Nice way shutdown failed.\n")); + s = context->_servers; + while (s) { + cli_shutdown(&s->cli); + context->callbacks.remove_cached_srv_fn(context, s); + SAFE_FREE(s); + s = s->next; + } + context->_servers = NULL; + } + } + else { + /* This is the polite way */ + if (context->callbacks.purge_cached_fn(context)) { + DEBUG(1, ("Could not purge all servers, free_context failed.\n")); + errno = EBUSY; + return 1; + } + if (context->_servers) { + DEBUG(1, ("Active servers in context, free_context failed.\n")); + errno = EBUSY; + return 1; + } + if (context->_files) { + DEBUG(1, ("Active files in context, free_context failed.\n")); + errno = EBUSY; + return 1; + } + } - if (!smbc_initialized) { + /* Things we have to clean up */ + SAFE_FREE(context->workgroup); + SAFE_FREE(context->netbios_name); + SAFE_FREE(context->user); + + DEBUG(3, ("Context %p succesfully freed\n", context)); + SAFE_FREE(context); + return 0; +} - errno = EINVAL; - return -1; +/* + * Initialise the library etc + * + * We accept a struct containing handle information. + * valid values for info->debug from 0 to 100, + * and insist that info->fn must be non-null. + */ +SMBCCTX * smbc_init_context(SMBCCTX * context) +{ + pstring conf; + int pid; + char *user = NULL, *home = NULL; + + if (!context) { + errno = EBADF; + return NULL; } - if (!fname) { + /* Do not initialise the same client twice */ + if (context->_initialized) { + return 0; + } + + if (!context->callbacks.auth_fn || context->debug < 0 || context->debug > 100) { errno = EINVAL; - return -1; + return NULL; } - - DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ - - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (!smbc_initialized) { + /* Do some library wide intialisations the first time we get called */ - pstrcpy(workgroup, lp_workgroup()); + /* Do we still need this ? */ + DEBUGLEVEL = 10; + + setup_logging( "libsmbclient", False); - srv = smbc_server(server, share, workgroup, user, password); + /* Here we would open the smb.conf file if needed ... */ + + home = getenv("HOME"); - if (!srv) { + slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); + + load_interfaces(); /* Load the list of interfaces ... */ + + in_client = True; /* FIXME, make a param */ - return -1; /* errno set by smbc_server */ + if (!lp_load(conf, True, False, False)) { - } + /* + * Hmmm, what the hell do we do here ... we could not parse the + * config file ... We must return an error ... and keep info around + * about why we failed + */ + + errno = ENOENT; /* FIXME: Figure out the correct error response */ + return NULL; + } - if ((err = cli_printjob_del(&srv->cli, id)) != 0) { + reopen_logs(); /* Get logging working ... */ + + /* + * Block SIGPIPE (from lib/util_sock.c: write()) + * It is not needed and should not stop execution + */ + BlockSignals(True, SIGPIPE); + + /* Done with one-time initialisation */ + smbc_initialized = 1; - if (err < 0) - errno = smbc_errno(&srv->cli); - else if (err == ERRnosuchprintjob) - errno = EINVAL; - return -1; + } + + if (!context->user) { + /* + * FIXME: Is this the best way to get the user info? + */ + user = getenv("USER"); + /* walk around as "guest" if no username can be found */ + if (!user) context->user = strdup("guest"); + else context->user = strdup(user); + } + if (!context->netbios_name) { + /* + * We try to get our netbios name from the config. If that fails we fall + * back on constructing our netbios name from our hostname etc + */ + if (global_myname) { + context->netbios_name = strdup(global_myname); + } + else { + /* + * Hmmm, I want to get hostname as well, but I am too lazy for the moment + */ + pid = sys_getpid(); + context->netbios_name = malloc(17); + if (!context->netbios_name) { + errno = ENOMEM; + return NULL; + } + slprintf(context->netbios_name, 16, "smbc%s%d", context->user, pid); + } + } + DEBUG(0,("Using netbios name %s.\n", context->netbios_name)); + + if (!context->workgroup) { + if (lp_workgroup()) { + context->workgroup = strdup(lp_workgroup()); + } + else { + /* TODO: Think about a decent default workgroup */ + context->workgroup = strdup("samba"); + } + } + DEBUG(0,("Using workgroup %s.\n", context->workgroup)); + + + /* + * I think we can do this more than once for the same name without + * being shot but who am I? -- Tom + * Actually, we probably don't want to register a name, + * but one day the user might want to be able to do so. RJS + */ + if (0) { + name_register_wins(context->netbios_name, 0); } - return 0; + /* shortest timeout is 1 second */ + if (context->timeout > 0 && context->timeout < 1000) + context->timeout = 1000; -} + /* + * FIXME: Should we check the function pointers here? + */ + context->_initialized = 1; + + return context; +} -- cgit From 1e8952c6849d0d5d4984a61080ab49ac2f64e43d Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 13 Jul 2002 05:11:58 +0000 Subject: Fix some multibyte problems that I forgot about. (This used to be commit 481a70f4f005a778a24e2193f8e760217ee3c946) --- source3/libsmb/libsmbclient.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 77a81c10c8..4100005425 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -122,8 +122,8 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, */ /* check that '@' occurs before '/', if '/' exists at all */ - q = strchr(p, '@'); - r = strchr(p, '/'); + q = strchr_m(p, '@'); + r = strchr_m(p, '/'); if (q && (!r || q < r)) { pstring username, passwd, domain; char *u = userinfo; @@ -132,13 +132,13 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, username[0] = passwd[0] = domain[0] = 0; - if (strchr(u, ';')) { + if (strchr_m(u, ';')) { next_token(&u, domain, ";", sizeof(fstring)); } - if (strchr(u, ':')) { + if (strchr_m(u, ':')) { next_token(&u, username, ":", sizeof(fstring)); @@ -342,11 +342,11 @@ SMBCSRV *smbc_server(SMBCCTX *context, DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server)); - if ((p=strchr(server_n,'#')) && + if ((p=strchr_m(server_n,'#')) && (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) { fstrcpy(group, server_n); - p = strchr(group,'#'); + p = strchr_m(group,'#'); *p = 0; } -- cgit From 5c682b73371c22e3e9abb620d4cdab10f7a78646 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 13 Jul 2002 05:13:02 +0000 Subject: Add these two files I forgot. (This used to be commit 5706e6af168b14a40cb1e306c2911182260ff0d3) --- source3/libsmb/libsmb_cache.c | 191 +++++++++++++++++++++++++++ source3/libsmb/libsmb_compat.c | 285 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 476 insertions(+) create mode 100644 source3/libsmb/libsmb_cache.c create mode 100644 source3/libsmb/libsmb_compat.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c new file mode 100644 index 0000000000..34b818ee74 --- /dev/null +++ b/source3/libsmb/libsmb_cache.c @@ -0,0 +1,191 @@ +/* + Unix SMB/CIFS implementation. + SMB client library implementation (server cache) + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 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 this to get the real SMBCFILE and SMBCSRV structures + */ +#define _SMBC_INTERNAL +#include "libsmbclient.h" + +/* + * Structure we use if internal caching mechanism is used + * nothing fancy here. + */ +struct smbc_server_cache { + char *server_name; + char *share_name; + char *workgroup; + char *username; + SMBCSRV *server; + + struct smbc_server_cache *next, *prev; +}; + + + +/* + * Add a new connection to the server cache. + * This function is only used if the external cache is not enabled + */ +static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * new, + char * server, char * share, + char * workgroup, char * username) +{ + struct smbc_server_cache * srvcache = NULL; + + if (!(srvcache = malloc(sizeof(*srvcache)))) { + errno = ENOMEM; + DEBUG(3, ("Not enough space for server cache allocation\n")); + return 1; + } + + ZERO_STRUCTP(srvcache); + + srvcache->server = new; + + srvcache->server_name = strdup(server); + if (!srvcache->server_name) { + errno = ENOMEM; + goto failed; + } + + srvcache->share_name = strdup(share); + if (!srvcache->share_name) { + errno = ENOMEM; + goto failed; + } + + srvcache->workgroup = strdup(workgroup); + if (!srvcache->workgroup) { + errno = ENOMEM; + goto failed; + } + + srvcache->username = strdup(username); + if (!srvcache->username) { + errno = ENOMEM; + goto failed; + } + + DLIST_ADD(((struct smbc_server_cache *)context->server_cache), srvcache); + return 0; + + failed: + SAFE_FREE(srvcache->server_name); + SAFE_FREE(srvcache->share_name); + SAFE_FREE(srvcache->workgroup); + SAFE_FREE(srvcache->username); + + return 1; +} + + + +/* + * Search the server cache for a server + * returns server_fd on success, -1 on error (not found) + * This function is only used if the external cache is not enabled + */ +static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, char * server, + char * share, char * workgroup, char * user) +{ + struct smbc_server_cache * srv = NULL; + + /* Search the cache lines */ + for (srv=((struct smbc_server_cache *)context->server_cache);srv;srv=srv->next) { + if (strcmp(server,srv->server_name) == 0 && + strcmp(share,srv->share_name) == 0 && + strcmp(workgroup,srv->workgroup) == 0 && + strcmp(user, srv->username) == 0) + return srv->server; + } + + return NULL; +} + + +/* + * Search the server cache for a server and remove it + * returns 0 on success + * This function is only used if the external cache is not enabled + */ +static int smbc_remove_cached_server(SMBCCTX * context, SMBCSRV * server) +{ + struct smbc_server_cache * srv = NULL; + + for (srv=((struct smbc_server_cache *)context->server_cache);srv;srv=srv->next) { + if (server == srv->server) { + + /* remove this sucker */ + DLIST_REMOVE(((struct smbc_server_cache *)context->server_cache), srv); + SAFE_FREE(srv->server_name); + SAFE_FREE(srv->share_name); + SAFE_FREE(srv->workgroup); + SAFE_FREE(srv->username); + SAFE_FREE(srv); + return 0; + } + } + /* server not found */ + return 1; +} + + +/* + * Try to remove all the servers in cache + * returns 1 on failure and 0 if all servers could be removed. + */ +static int smbc_purge_cached(SMBCCTX * context) +{ + struct smbc_server_cache * srv = NULL; + int could_not_purge_all = 0; + + for (srv=((struct smbc_server_cache *) context->server_cache);srv;srv=srv->next) { + if (smbc_remove_unused_server(context, srv->server)) { + /* could not be removed */ + could_not_purge_all = 1; + } + } + return could_not_purge_all; +} + + + +/* + * This functions initializes all server-cache related functions + * to the default (internal) system. + * + * We use this to make the rest of the cache system static. + */ + +int smbc_default_cache_functions(SMBCCTX * context) +{ + context->callbacks.add_cached_srv_fn = smbc_add_cached_server; + context->callbacks.get_cached_srv_fn = smbc_get_cached_server; + context->callbacks.remove_cached_srv_fn = smbc_remove_cached_server; + context->callbacks.purge_cached_fn = smbc_purge_cached; + + return 0; +} diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c new file mode 100644 index 0000000000..dbfd860358 --- /dev/null +++ b/source3/libsmb/libsmb_compat.c @@ -0,0 +1,285 @@ +/* + Unix SMB/CIFS implementation. + SMB client library implementation (Old interface compatibility) + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 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 this to get the real SMBCFILE and SMBCSRV structures + */ +#define _SMBC_INTERNAL +#include "libsmbclient.h" + +struct smbc_compat_fdlist { + SMBCFILE * file; + int fd; + struct smbc_compat_fdlist *next, *prev; +}; + +static SMBCCTX * statcont = NULL; +static int smbc_compat_initialized = 0; +static int smbc_currentfd = 10000; +static struct smbc_compat_fdlist * smbc_compat_fdlist = NULL; + + +/* Find an fd and return the SMBCFILE * or NULL on failure */ +static SMBCFILE * find_fd(int fd) +{ + struct smbc_compat_fdlist * f = smbc_compat_fdlist; + while (f) { + if (f->fd == fd) + return f->file; + f = f->next; + } + return NULL; +} + +/* Add an fd, returns 0 on success, -1 on error with errno set */ +static int add_fd(SMBCFILE * file) +{ + struct smbc_compat_fdlist * f = malloc(sizeof(struct smbc_compat_fdlist)); + if (!f) { + errno = ENOMEM; + return -1; + } + + f->fd = smbc_currentfd++; + f->file = file; + + DLIST_ADD(smbc_compat_fdlist, f); + + return f->fd; +} + + + +/* Delete an fd, returns 0 on success */ +static int del_fd(int fd) +{ + struct smbc_compat_fdlist * f = smbc_compat_fdlist; + while (f) { + if (f->fd == fd) + break; + f = f->next; + } + if (f) { + /* found */ + DLIST_REMOVE(smbc_compat_fdlist, f); + SAFE_FREE(f); + return 0; + } + return 1; +} + + + +int smbc_init(smbc_get_auth_data_fn fn, int debug) +{ + if (!smbc_compat_initialized) { + statcont = smbc_new_context(); + if (!statcont) + return -1; + + statcont->debug = debug; + statcont->callbacks.auth_fn = fn; + + if (!smbc_init_context(statcont)) { + smbc_free_context(statcont, False); + return -1; + } + + smbc_compat_initialized = 1; + + return 0; + } + return 0; +} + + +int smbc_open(const char *furl, int flags, mode_t mode) +{ + SMBCFILE * file; + int fd; + + file = statcont->open(statcont, furl, flags, mode); + if (!file) + return -1; + + fd = add_fd(file); + if (fd == -1) + statcont->close(statcont, file); + return fd; +} + + +int smbc_creat(const char *furl, mode_t mode) +{ + SMBCFILE * file; + int fd; + + file = statcont->creat(statcont, furl, mode); + if (!file) + return -1; + + fd = add_fd(file); + if (fd == -1) { + /* Hmm... should we delete the file too ? I guess we could try */ + statcont->close(statcont, file); + statcont->unlink(statcont, furl); + } + return fd; +} + + +ssize_t smbc_read(int fd, void *buf, size_t bufsize) +{ + SMBCFILE * file = find_fd(fd); + return statcont->read(statcont, file, buf, bufsize); +} + +ssize_t smbc_write(int fd, void *buf, size_t bufsize) +{ + SMBCFILE * file = find_fd(fd); + return statcont->write(statcont, file, buf, bufsize); +} + +off_t smbc_lseek(int fd, off_t offset, int whence) +{ + SMBCFILE * file = find_fd(fd); + return statcont->lseek(statcont, file, offset, whence); +} + +int smbc_close(int fd) +{ + SMBCFILE * file = find_fd(fd); + del_fd(fd); + return statcont->close(statcont, file); +} + +int smbc_unlink(const char *fname) +{ + return statcont->unlink(statcont, fname); +} + +int smbc_rename(const char *ourl, const char *nurl) +{ + return statcont->rename(statcont, ourl, statcont, nurl); +} + +int smbc_opendir(const char *durl) +{ + SMBCFILE * file; + int fd; + + file = statcont->opendir(statcont, durl); + if (!file) + return -1; + + fd = add_fd(file); + if (fd == -1) + statcont->closedir(statcont, file); + + return fd; +} + +int smbc_closedir(int dh) +{ + SMBCFILE * file = find_fd(dh); + del_fd(dh); + return statcont->closedir(statcont, file); +} + +int smbc_getdents(unsigned int dh, struct smbc_dirent *dirp, int count) +{ + SMBCFILE * file = find_fd(dh); + return statcont->getdents(statcont, file,dirp, count); +} + +struct smbc_dirent* smbc_readdir(unsigned int dh) +{ + SMBCFILE * file = find_fd(dh); + return statcont->readdir(statcont, file); +} + +off_t smbc_telldir(int dh) +{ + SMBCFILE * file = find_fd(dh); + return statcont->telldir(statcont, file); +} + +int smbc_lseekdir(int fd, off_t offset) +{ + SMBCFILE * file = find_fd(fd); + return statcont->lseekdir(statcont, file, offset); +} + +int smbc_mkdir(const char *durl, mode_t mode) +{ + return statcont->mkdir(statcont, durl, mode); +} + +int smbc_rmdir(const char *durl) +{ + return statcont->rmdir(statcont, durl); +} + +int smbc_stat(const char *url, struct stat *st) +{ + return statcont->stat(statcont, url, st); +} + +int smbc_fstat(int fd, struct stat *st) +{ + SMBCFILE * file = find_fd(fd); + return statcont->fstat(statcont, file, st); +} + +int smbc_chmod(const char *url, mode_t mode) +{ + /* NOT IMPLEMENTED IN LIBSMBCLIENT YET */ + return -1; +} + +int smbc_print_file(const char *fname, const char *printq) +{ + return statcont->print_file(statcont, fname, statcont, printq); +} + +int smbc_open_print_job(const char *fname) +{ + SMBCFILE * file = statcont->open_print_job(statcont, fname); + if (!file) return -1; + return (int) file; +} + +int smbc_list_print_jobs(const char *purl, smbc_get_print_job_info fn) +{ + return statcont->list_print_jobs(statcont, purl, fn); +} + +int smbc_unlink_print_job(const char *purl, int id) +{ + return statcont->unlink_print_job(statcont, purl, id); +} + + -- cgit From 92c597a9b07ebffafd96ba11f0b25f8b97ffb124 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 13 Jul 2002 05:43:34 +0000 Subject: Fix up the include file that had problems as well. (This used to be commit 753df0b89767261420f242da21d5dfb5403c966b) --- source3/libsmb/libsmbclient.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 4100005425..05b6b3121f 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2633,18 +2633,7 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) } } DEBUG(0,("Using workgroup %s.\n", context->workgroup)); - - /* - * I think we can do this more than once for the same name without - * being shot but who am I? -- Tom - * Actually, we probably don't want to register a name, - * but one day the user might want to be able to do so. RJS - */ - if (0) { - name_register_wins(context->netbios_name, 0); - } - /* shortest timeout is 1 second */ if (context->timeout > 0 && context->timeout < 1000) context->timeout = 1000; -- cgit From 3faee01c7c49c92eb6859bea19479e88b446e54e Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 13 Jul 2002 07:18:43 +0000 Subject: Some fix ups but committing so Andrew can look at the problem I have. (This used to be commit 146ba3eb49bade732d57691d8ce181ef6608e0cb) --- source3/libsmb/libsmbclient.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 05b6b3121f..0ffc1c1378 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1,6 +1,5 @@ /* Unix SMB/Netbios implementation. - Version 2.0 SMB client library implementation Copyright (C) Andrew Tridgell 1998 Copyright (C) Richard Sharpe 2000, 2002 @@ -24,17 +23,12 @@ #include "includes.h" -/* - * Define this to get the real SMBCFILE and SMBCSRV structures - */ -#define _SMBC_INTERNAL - #include "libsmbclient.h" /* * Functions exported by libsmb_cache.c that we need here */ -int smbc_default_cache_functions(SMBCCTX * context); +int smbc_default_cache_functions(SMBCCTX *context); /* * check if an element is part of the list. -- cgit From f5b6ef1b65bdf99ac31d23c80ead330da2cd1411 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 13 Jul 2002 08:37:06 +0000 Subject: fix directory listing on win9x. it turns out this is tricky to get right for both win9x and w2k with and without unicode. This patch seems to do the trick. (This used to be commit 01ebe5fff2b3cb29f083afb224b1257364ac5d80) --- source3/libsmb/clilist.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 8b28e05a47..17a759f9e3 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -54,10 +54,14 @@ static int interpret_long_filename(struct cli_state *cli, len = CVAL(p, 26); p += 27; p += clistr_align_in(cli, p, 0); + /* the len+2 below looks strange but it is + important to cope with the differences + between win2000 and win9x for this call + (tridge) */ p += clistr_pull(cli, finfo->name, p, - sizeof(finfo->name), - len, - STR_TERMINATE); + sizeof(finfo->name), + len+2, + STR_TERMINATE); return PTR_DIFF(p, base); case 2: /* this is what OS/2 uses mostly */ -- cgit