diff options
author | cvs2svn Import User <samba-bugs@samba.org> | 2002-07-14 22:15:21 +0000 |
---|---|---|
committer | cvs2svn Import User <samba-bugs@samba.org> | 2002-07-14 22:15:21 +0000 |
commit | ec167dc9cc0ec2ee461837c25a371d2981744208 (patch) | |
tree | 2703197421fecfa142935091760c2d4a60f10552 /source3/libsmb | |
parent | a2c8ca186f7261fdab49ed40949320a45868d2b5 (diff) | |
parent | 13157d1494b99bf85632120c27286ba4d877a68f (diff) | |
download | samba-ec167dc9cc0ec2ee461837c25a371d2981744208.tar.gz samba-ec167dc9cc0ec2ee461837c25a371d2981744208.tar.bz2 samba-ec167dc9cc0ec2ee461837c25a371d2981744208.zip |
This commit was manufactured by cvs2svn to create branch 'SAMBA_3_0'.(This used to be commit b8d39651fb90ef170055735412417239a63afc5d)
Diffstat (limited to 'source3/libsmb')
-rw-r--r-- | source3/libsmb/cli_spoolss_notify.c | 223 | ||||
-rw-r--r-- | source3/libsmb/libsmb_cache.c | 191 | ||||
-rw-r--r-- | source3/libsmb/libsmb_compat.c | 285 |
3 files changed, 699 insertions, 0 deletions
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; +} 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); +} + + |