The branch, master has been updated via c586c3d libgpo: allow empty values in gp inifile parsing code. via 7eeb2ed lib/util: add pm_process_with_flags to allow parsing ini files with empty values via 235aa67 libgpo: default to empty values if none are there via 06978c6 libgpo: deal with non utf16-le ini files. via dcb2680 libgpo: apply some const. via 8e5251c libgpo: add gp_inifile_enum_section() via 5c16dfe libgpo: add gp_inifile_init_context_direct() via 90deb9f s3-spoolss: Create a sperate header file for 'struct printer_handle' via bb24649 s3-spoolss: remove unused type field in printer handle via a250184 s3-iremotewinspool: update api struct map so we only end up implementing 8 calls via 7dd880f s3-iremotewinspool: add generated server stubs and no longer compile autogenerated ones via 29266c0 s3-iremotewinspool: add generated srv_iremotewinspool_nt.c file via 5674655 s3-rpc_server: setup secondary address for tcp transport in bind_ack packet. via 3e084ea s3-rpc_server: enforce packet level authentication for iremotewinspool server via 1ec825b s3-rpc_server: allow to set minimal auth level for a DCE/RPC service from 4635c22 ctdb-tests: Do not attempt to unregister the join handler multiple times
https://git.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit c586c3d962e8ee57e90f76147b458e1bea0ed988 Author: Günther Deschner <g...@samba.org> Date: Wed Sep 14 18:13:39 2016 +0200 libgpo: allow empty values in gp inifile parsing code. Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> Autobuild-User(master): Andreas Schneider <a...@cryptomilk.org> Autobuild-Date(master): Fri Jan 6 16:16:02 CET 2017 on sn-devel-144 commit 7eeb2edc5060b03efa7166017e5b2a36af5b7f75 Author: Günther Deschner <g...@samba.org> Date: Wed Sep 14 18:13:00 2016 +0200 lib/util: add pm_process_with_flags to allow parsing ini files with empty values Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 235aa6754471122bd5791614953eeea6d86e2a5e Author: Günther Deschner <g...@samba.org> Date: Mon Sep 19 17:11:19 2016 +0200 libgpo: default to empty values if none are there Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 06978c65414a3afb25e22d40379208ca3857bcbc Author: Günther Deschner <g...@samba.org> Date: Thu Nov 10 15:15:05 2016 +0100 libgpo: deal with non utf16-le ini files. Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit dcb26801632d354e4037f146f89d55448fbbb622 Author: Günther Deschner <g...@samba.org> Date: Tue Sep 27 18:18:51 2016 +0200 libgpo: apply some const. Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 8e5251c1f30a86ef88c7c145c71deccf19d4189f Author: Günther Deschner <g...@samba.org> Date: Tue Sep 13 08:36:59 2016 +0200 libgpo: add gp_inifile_enum_section() Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 5c16dfe32532e06c7fe9fad6524ebef7d7378b76 Author: Günther Deschner <g...@samba.org> Date: Sun Sep 11 12:48:14 2016 +0200 libgpo: add gp_inifile_init_context_direct() This varient ignores the group policy flags and does not try to find the right unix path. Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 90deb9f04c5ac1b2ef3ced35d927abb139d3e789 Author: Günther Deschner <g...@samba.org> Date: Fri Aug 26 18:33:19 2016 +0200 s3-spoolss: Create a sperate header file for 'struct printer_handle' Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit bb24649051d95ee8d3e968496d77e43b4c433563 Author: Günther Deschner <g...@samba.org> Date: Fri Dec 2 09:09:49 2016 +0100 s3-spoolss: remove unused type field in printer handle Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit a2501843b6a93c09918825e2f04726ab843c2107 Author: Günther Deschner <g...@samba.org> Date: Wed Sep 14 11:46:20 2016 +0200 s3-iremotewinspool: update api struct map so we only end up implementing 8 calls In the end, these calls are the only ones we need to implement: 3.1.4.2. Printer Driver Management Methods * AsyncInstallPrinterDriverFromPackage * AsyncUploadPrinterDriverPackage * AsyncCorePrinterDriverInstalled * AsyncDeletePrinterDriverPackage 3.1.4.9. Printing Related Notification Methods * SyncRegisterForRemoteNotifications * SyncUnRegisterForRemoteNotifications * SyncRefreshRemoteNotifications * AsyncGetRemoteNotifications All other calls are 1:1 mapped to spoolss calls. Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 7dd880f4b91dd55f800fe3b7097684acdd3297ca Author: Günther Deschner <g...@samba.org> Date: Tue Sep 20 18:43:57 2016 +0200 s3-iremotewinspool: add generated server stubs and no longer compile autogenerated ones Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 29266c0a9075d466a2e580206e9018b278bce972 Author: Günther Deschner <g...@samba.org> Date: Tue Sep 20 20:21:50 2016 +0200 s3-iremotewinspool: add generated srv_iremotewinspool_nt.c file Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 567465546f112fda90f59bbeeba0bff3d4985bcd Author: Günther Deschner <g...@samba.org> Date: Mon Sep 26 20:22:04 2016 +0200 s3-rpc_server: setup secondary address for tcp transport in bind_ack packet. Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 3e084ea6ceb82b61c24ce7260404027a4428b9d6 Author: Günther Deschner <g...@samba.org> Date: Mon Sep 26 19:21:05 2016 +0200 s3-rpc_server: enforce packet level authentication for iremotewinspool server Guenther Signed-off-by: Guenther Deschner <g...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> commit 1ec825b28a296d7df11fd9ac83a6c123c7b177ea Author: Günther Deschner <g...@samba.org> Date: Mon Sep 26 19:20:24 2016 +0200 s3-rpc_server: allow to set minimal auth level for a DCE/RPC service Guenther Pair-Programmed-With: Stefan Metzmacher <me...@samba.org> Signed-off-by: Guenther Deschner <g...@samba.org> Signed-off-by: Stefan Metzmacher <me...@samba.org> Reviewed-by: Andreas Schneider <a...@samba.org> ----------------------------------------------------------------------- Summary of changes: lib/util/params.c | 25 +- lib/util/samba_util.h | 6 + lib/util/tini.c | 25 +- lib/util/tini.h | 1 + lib/util/tiniparser.c | 1 + libgpo/gpo_ini.c | 168 +++- libgpo/gpo_ini.h | 15 +- source3/include/nt_printing.h | 5 - source3/libgpo/gpext/scripts.c | 4 +- source3/libgpo/gpext/security.c | 2 +- source3/rpc_server/rpc_pipes.h | 5 + source3/rpc_server/spoolss/srv_iremotewinspool.c | 723 ++++++++++++++++ .../rpc_server/spoolss/srv_iremotewinspool_nt.c | 923 +++++++++++++++++++++ source3/rpc_server/spoolss/srv_spoolss_handle.h | 77 ++ source3/rpc_server/spoolss/srv_spoolss_nt.c | 43 +- source3/rpc_server/srv_pipe.c | 41 +- source3/rpc_server/wscript_build | 9 +- 17 files changed, 1988 insertions(+), 85 deletions(-) create mode 100644 source3/rpc_server/spoolss/srv_iremotewinspool.c create mode 100644 source3/rpc_server/spoolss/srv_iremotewinspool_nt.c create mode 100644 source3/rpc_server/spoolss/srv_spoolss_handle.h Changeset truncated at 500 lines: diff --git a/lib/util/params.c b/lib/util/params.c index 5ec4fd2..c5c2526 100644 --- a/lib/util/params.c +++ b/lib/util/params.c @@ -96,7 +96,30 @@ bool pm_process(const char *filename, return false; } - ret = tini_parse(f, sfunc, pfunc, private_data); + ret = tini_parse(f, false, sfunc, pfunc, private_data); + + fclose(f); + + return ret; +} + + +bool pm_process_with_flags(const char *filename, + bool allow_empty_values, + bool (*sfunc)(const char *section, void *private_data), + bool (*pfunc)(const char *name, const char *value, + void *private_data), + void *private_data) +{ + FILE *f; + bool ret; + + f = fopen(filename, "r"); + if (f == NULL) { + return false; + } + + ret = tini_parse(f, allow_empty_values, sfunc, pfunc, private_data); fclose(f); diff --git a/lib/util/samba_util.h b/lib/util/samba_util.h index 897e0f5..c19e246 100644 --- a/lib/util/samba_util.h +++ b/lib/util/samba_util.h @@ -609,6 +609,12 @@ bool pm_process( const char *fileName, bool (*sfunc)(const char *, void *), bool (*pfunc)(const char *, const char *, void *), void *userdata); +bool pm_process_with_flags(const char *filename, + bool allow_empty_values, + bool (*sfunc)(const char *section, void *private_data), + bool (*pfunc)(const char *name, const char *value, + void *private_data), + void *private_data); void print_asc(int level, const uint8_t *buf,int len); void print_asc_cb(const uint8_t *buf, int len, diff --git a/lib/util/tini.c b/lib/util/tini.c index 3bfc2d6..36d7a45 100644 --- a/lib/util/tini.c +++ b/lib/util/tini.c @@ -227,19 +227,27 @@ static char *trim_one_space(char *buf) } static bool parse_param(char *buf, + bool allow_empty_value, bool (*pfunc)(const char *name, const char *value, void *private_data), void *private_data) { char *equals; - char *name, *value; + char *name; + const char *value; size_t len; + bool no_value = false; equals = strchr(buf, '='); - if (equals == NULL) { - return true; + if (equals != NULL) { + *equals = '\0'; + } else { + if (allow_empty_value) { + no_value = true; + } else { + return true; + } } - *equals = '\0'; name = trim_one_space(buf); len = strlen(buf); @@ -247,12 +255,17 @@ static bool parse_param(char *buf, return false; } - value = trim_one_space(equals+1); + if (no_value) { + value = ""; + } else { + value = trim_one_space(equals+1); + } return pfunc(name, value, private_data); } bool tini_parse(FILE *f, + bool allow_empty_value, bool (*sfunc)(const char *section, void *private_data), bool (*pfunc)(const char *name, const char *value, void *private_data), @@ -293,7 +306,7 @@ bool tini_parse(FILE *f, ok = parse_section(buf, sfunc, private_data); break; default: - ok = parse_param(buf, pfunc, private_data); + ok = parse_param(buf, allow_empty_value, pfunc, private_data); break; } diff --git a/lib/util/tini.h b/lib/util/tini.h index 02cc1ac..36fc080 100644 --- a/lib/util/tini.h +++ b/lib/util/tini.h @@ -38,6 +38,7 @@ #include <stdio.h> bool tini_parse(FILE *f, + bool allow_empty_value, bool (*sfunc)(const char *section, void *private_data), bool (*pfunc)(const char *name, const char *value, void *private_data), diff --git a/lib/util/tiniparser.c b/lib/util/tiniparser.c index 7c10616..c3ab4e7 100644 --- a/lib/util/tiniparser.c +++ b/lib/util/tiniparser.c @@ -339,6 +339,7 @@ struct tiniparser_dictionary *tiniparser_load(const char *filename) d->section_list = NULL; ret = tini_parse(fp, + false, section_parser, value_parser, d); diff --git a/libgpo/gpo_ini.c b/libgpo/gpo_ini.c index c027612..198e8af 100644 --- a/libgpo/gpo_ini.c +++ b/libgpo/gpo_ini.c @@ -56,7 +56,7 @@ static bool store_keyval_pair(const char *key, const char *value, void *ctx_ptr) } ctx->data[ctx->keyval_count]->key = talloc_asprintf(ctx, "%s:%s", ctx->current_section, key); - ctx->data[ctx->keyval_count]->val = talloc_strdup(ctx, value); + ctx->data[ctx->keyval_count]->val = talloc_strdup(ctx, value ? value : ""); if (!ctx->data[ctx->keyval_count]->key || !ctx->data[ctx->keyval_count]->val) { @@ -87,12 +87,22 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx, return NT_STATUS_INVALID_PARAMETER; } - data_in = (uint8_t *)file_load(filename_in, &n, 0, NULL); + data_in = (uint8_t *)file_load(filename_in, &n, 0, mem_ctx); if (!data_in) { status = NT_STATUS_NO_SUCH_FILE; goto out; } + DEBUG(11,("convert_file_from_ucs2: " + "data_in[0]: 0x%x, data_in[1]: 0x%x, data_in[2]: 0x%x\n", + data_in[0], data_in[1], data_in[2])); + + if ((data_in[0] != 0xff) || (data_in[1] != 0xfe) || (data_in[2] != 0x0d)) { + *filename_out = NULL; + status = NT_STATUS_OK; + goto out; + } + tmp_name = talloc_asprintf(mem_ctx, "%s/convert_file_from_ucs2.XXXXXX", tmpdir()); if (!tmp_name) { @@ -115,20 +125,12 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx, goto out; } - /* skip utf8 BOM */ DEBUG(11,("convert_file_from_ucs2: " - "data_out[0]: 0x%x, data_out[1]: 0x%x, data_out[2]: 0x%x\n", - data_out[0], data_out[1], data_out[2])); + "%s skipping utf16-le BOM\n", tmp_name)); - if ((data_out[0] == 0xef) && (data_out[1] == 0xbb) && - (data_out[2] == 0xbf)) { - DEBUG(11,("convert_file_from_ucs2: " - "%s skipping utf8 BOM\n", tmp_name)); - data_out += 3; - converted_size -= 3; - } + converted_size -= 3; - if (write(tmp_fd, data_out, converted_size) != converted_size) { + if (write(tmp_fd, data_out + 3, converted_size) != converted_size) { status = map_nt_error_from_unix_common(errno); goto out; } @@ -143,6 +145,7 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx, } talloc_free(data_in); + talloc_free(data_out); return status; } @@ -150,7 +153,7 @@ static NTSTATUS convert_file_from_ucs2(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ -NTSTATUS gp_inifile_getstring(struct gp_inifile_context *ctx, const char *key, char **ret) +NTSTATUS gp_inifile_getstring(struct gp_inifile_context *ctx, const char *key, const char **ret) { int i; @@ -170,7 +173,7 @@ NTSTATUS gp_inifile_getstring(struct gp_inifile_context *ctx, const char *key, c NTSTATUS gp_inifile_getint(struct gp_inifile_context *ctx, const char *key, int *ret) { - char *value; + const char *value; NTSTATUS result; result = gp_inifile_getstring(ctx,key, &value); @@ -189,7 +192,7 @@ NTSTATUS gp_inifile_getint(struct gp_inifile_context *ctx, const char *key, int NTSTATUS gp_inifile_getbool(struct gp_inifile_context *ctx, const char *key, bool *ret) { - char *value; + const char *value; NTSTATUS result; result = gp_inifile_getstring(ctx,key, &value); @@ -217,6 +220,80 @@ NTSTATUS gp_inifile_getbool(struct gp_inifile_context *ctx, const char *key, boo /**************************************************************** ****************************************************************/ +NTSTATUS gp_inifile_enum_section(struct gp_inifile_context *ctx, + const char *section, + size_t *num_ini_keys, + const char ***ini_keys, + const char ***ini_values) +{ + NTSTATUS status; + int i; + size_t num_keys = 0, num_vals = 0; + const char **keys = NULL; + const char **values = NULL; + + if (section == NULL || num_ini_keys == NULL || + ini_keys == NULL || ini_values == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + for (i = 0; i < ctx->keyval_count; i++) { + + bool ok; + + /* + * section: KEYNAME + * KEYNAME:value matches + * KEYNAME_OEM:value not + */ + + if (strlen(section)+1 > strlen(ctx->data[i]->key)) { + continue; + } + + if (!strnequal(section, ctx->data[i]->key, strlen(section))) { + continue; + } + + if (ctx->data[i]->key[strlen(section)] != ':') { + continue; + } + + ok = add_string_to_array(ctx, ctx->data[i]->key, &keys, &num_keys); + if (!ok) { + status = NT_STATUS_NO_MEMORY; + goto failed; + } + + ok = add_string_to_array(ctx, ctx->data[i]->val, &values, &num_vals); + if (!ok) { + status = NT_STATUS_NO_MEMORY; + goto failed; + } + + if (num_keys != num_vals) { + status = NT_STATUS_INTERNAL_DB_CORRUPTION; + goto failed; + } + } + + *num_ini_keys = num_keys; + *ini_keys = keys; + *ini_values = values; + + return NT_STATUS_OK; + + failed: + talloc_free(keys); + talloc_free(values); + + return status; +} + + +/**************************************************************** +****************************************************************/ + NTSTATUS gp_inifile_init_context(TALLOC_CTX *mem_ctx, uint32_t flags, const char *unix_path, @@ -249,7 +326,8 @@ NTSTATUS gp_inifile_init_context(TALLOC_CTX *mem_ctx, goto failed; } - rv = pm_process(tmp_filename, change_section, store_keyval_pair, ctx); + rv = pm_process(tmp_filename != NULL ? tmp_filename : ini_filename, + change_section, store_keyval_pair, ctx); if (!rv) { return NT_STATUS_NO_SUCH_FILE; } @@ -273,6 +351,60 @@ NTSTATUS gp_inifile_init_context(TALLOC_CTX *mem_ctx, } /**************************************************************** +****************************************************************/ + +NTSTATUS gp_inifile_init_context_direct(TALLOC_CTX *mem_ctx, + const char *unix_path, + struct gp_inifile_context **pgp_ctx) +{ + struct gp_inifile_context *gp_ctx = NULL; + NTSTATUS status; + int rv; + char *tmp_filename = NULL; + + if (unix_path == NULL || pgp_ctx == NULL) { + return NT_STATUS_INVALID_PARAMETER; + } + + gp_ctx = talloc_zero(mem_ctx, struct gp_inifile_context); + if (gp_ctx == NULL) { + return NT_STATUS_NO_MEMORY; + } + + status = convert_file_from_ucs2(mem_ctx, unix_path, + &tmp_filename); + if (!NT_STATUS_IS_OK(status)) { + goto failed; + } + + rv = pm_process_with_flags(tmp_filename != NULL ? tmp_filename : unix_path, + true, + change_section, + store_keyval_pair, + gp_ctx); + if (rv != 0) { + return NT_STATUS_NO_SUCH_FILE; + } + + gp_ctx->generated_filename = tmp_filename; + gp_ctx->mem_ctx = mem_ctx; + + *pgp_ctx = gp_ctx; + + return NT_STATUS_OK; + + failed: + + DEBUG(1,("gp_inifile_init_context_direct failed: %s\n", + nt_errstr(status))); + + talloc_free(gp_ctx); + + return status; +} + + +/**************************************************************** parse the local gpt.ini file ****************************************************************/ @@ -288,7 +420,7 @@ NTSTATUS parse_gpt_ini(TALLOC_CTX *mem_ctx, NTSTATUS result; int rv; int v = 0; - char *name = NULL; + const char *name = NULL; struct gp_inifile_context *ctx; if (!filename) { diff --git a/libgpo/gpo_ini.h b/libgpo/gpo_ini.h index c9afec0..0bfe5b1 100644 --- a/libgpo/gpo_ini.h +++ b/libgpo/gpo_ini.h @@ -18,8 +18,8 @@ */ struct keyval_pair { - char *key; - char *val; + const char *key; + const char *val; }; struct gp_inifile_context { @@ -35,12 +35,19 @@ struct gp_inifile_context { NTSTATUS gp_inifile_init_context(TALLOC_CTX *mem_ctx, uint32_t flags, const char *unix_path, const char *suffix, struct gp_inifile_context **ctx_ret); - +NTSTATUS gp_inifile_init_context_direct(TALLOC_CTX *mem_ctx, + const char *unix_path, + struct gp_inifile_context **ctx_ret); NTSTATUS parse_gpt_ini(TALLOC_CTX *ctx, const char *filename, uint32_t *version, char **display_name); -NTSTATUS gp_inifile_getstring(struct gp_inifile_context *ctx, const char *key, char **ret); +NTSTATUS gp_inifile_getstring(struct gp_inifile_context *ctx, const char *key, const char **ret); NTSTATUS gp_inifile_getint(struct gp_inifile_context *ctx, const char *key, int *ret); NTSTATUS gp_inifile_getbool(struct gp_inifile_context *ctx, const char *key, bool *ret); +NTSTATUS gp_inifile_enum_section(struct gp_inifile_context *ctx, + const char *section, + size_t *num_ini_keys, + const char ***ini_keys, + const char ***ini_values); diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h index e0003f9..688c6b9 100644 --- a/source3/include/nt_printing.h +++ b/source3/include/nt_printing.h @@ -97,11 +97,6 @@ typedef struct { SPOOLSS_NOTIFY_MSG_GROUP *msg_groups; } SPOOLSS_NOTIFY_MSG_CTR; -#define SPLHND_PRINTER 1 -#define SPLHND_SERVER 2 -#define SPLHND_PORTMON_TCP 3 -#define SPLHND_PORTMON_LOCAL 4 - /* * The printer attributes. * I #defined all of them (grabbed form MSDN) diff --git a/source3/libgpo/gpext/scripts.c b/source3/libgpo/gpext/scripts.c index 12e17b1e..7471fb8 100644 --- a/source3/libgpo/gpext/scripts.c +++ b/source3/libgpo/gpext/scripts.c @@ -138,9 +138,9 @@ static NTSTATUS scripts_parse_ini_section(struct gp_inifile_context *ini_ctx, while (1) { const char *key = NULL; - char *script = NULL; + const char *script = NULL; const char *count = NULL; - char *parameters = NULL; + const char *parameters = NULL; count = talloc_asprintf(ini_ctx->mem_ctx, "%d", i); NT_STATUS_HAVE_NO_MEMORY(count); diff --git a/source3/libgpo/gpext/security.c b/source3/libgpo/gpext/security.c index 2f46184..dda58d3 100644 --- a/source3/libgpo/gpext/security.c +++ b/source3/libgpo/gpext/security.c @@ -62,7 +62,7 @@ struct gpttmpl_table { static NTSTATUS gpttmpl_parse_header(struct gp_inifile_context *ini_ctx, uint32_t *version_out) { - char *signature = NULL; + const char *signature = NULL; NTSTATUS result; int version; bool is_unicode = false; diff --git a/source3/rpc_server/rpc_pipes.h b/source3/rpc_server/rpc_pipes.h index d44ee92..8a8f8e5 100644 --- a/source3/rpc_server/rpc_pipes.h +++ b/source3/rpc_server/rpc_pipes.h @@ -98,6 +98,11 @@ struct pipe_rpc_fns { * shall we allow "connect" auth level for this interface ? */ bool allow_connect; + + /* + * minimal required auth level + */ + enum dcerpc_AuthLevel min_auth_level; }; /* diff --git a/source3/rpc_server/spoolss/srv_iremotewinspool.c b/source3/rpc_server/spoolss/srv_iremotewinspool.c new file mode 100644 index 0000000..ea52348 --- /dev/null -- Samba Shared Repository