summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
authorjoyce mcintosh <Joyce.McIntosh@Sun.COM>2010-08-11 16:48:54 -0700
committerjoyce mcintosh <Joyce.McIntosh@Sun.COM>2010-08-11 16:48:54 -0700
commitfd9ee8b58485b20072eeef1310a88ff348d5e7fa (patch)
tree74e8f3fc5f5409cdc6be3dae5631f8d0c672260a /usr/src/lib
parente2c5185af3c50d9510e5df68aa37abdc6c0d3aac (diff)
downloadillumos-joyent-fd9ee8b58485b20072eeef1310a88ff348d5e7fa.tar.gz
6972305 Preferred DC not selected after setting pdc via sharectl
6971047 smbd hang during FVT regression test 6711195 Sparc:Get error "Windows Explorer has stopped working" once click on Details fr Properties on Vista PSARC/2009/464 Offline attribute 6972515 Offline attribute - PSARC 2009/464 PSARC/2010/037 Windows Sparse Attribute 6972519 Windows Sparse Attribute - PSARC 2010/037 6719444 [CLI] - idmap help's output is not consistent with man pages's 6975449 idmap test suite needs idmap_cache_get_data() from libidmap 6974351 OpenSSL still taking smbd down --HG-- rename : usr/src/lib/libidmap/common/idmap_priv.h => usr/src/cmd/idmap/idmap/namemaps.h
Diffstat (limited to 'usr/src/lib')
-rw-r--r--usr/src/lib/libidmap/common/mapfile-vers1
-rw-r--r--usr/src/lib/libzpool/common/sys/zfs_context.h2
-rw-r--r--usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c1
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h8
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/lsar_svc.c113
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers2
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h21
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/smb_share.c82
-rw-r--r--usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c1039
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/libsmb.h19
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/mapfile-vers1
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_cfg.c17
-rw-r--r--usr/src/lib/smbsrv/libsmb/common/smb_kmod.c6
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/libsmbns.h6
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/mapfile-vers1
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c7
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c55
17 files changed, 666 insertions, 715 deletions
diff --git a/usr/src/lib/libidmap/common/mapfile-vers b/usr/src/lib/libidmap/common/mapfile-vers
index 7a57d184c9..fba4b644ef 100644
--- a/usr/src/lib/libidmap/common/mapfile-vers
+++ b/usr/src/lib/libidmap/common/mapfile-vers
@@ -60,6 +60,7 @@ SYMBOL_VERSION SUNWprivate {
directory_sid_from_group_name;
directory_sid_from_name;
directory_sid_from_user_name;
+ idmap_cache_get_data; # used by idmap test suite
idmap_flush;
idmap_free;
idmap_get_create;
diff --git a/usr/src/lib/libzpool/common/sys/zfs_context.h b/usr/src/lib/libzpool/common/sys/zfs_context.h
index 51130b86d8..fc543559bd 100644
--- a/usr/src/lib/libzpool/common/sys/zfs_context.h
+++ b/usr/src/lib/libzpool/common/sys/zfs_context.h
@@ -401,6 +401,8 @@ typedef struct xoptattr {
uint8_t xoa_av_modified;
uint8_t xoa_av_scanstamp[AV_SCANSTAMP_SZ];
uint8_t xoa_reparse;
+ uint8_t xoa_offline;
+ uint8_t xoa_sparse;
} xoptattr_t;
typedef struct vattr {
diff --git a/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c b/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c
index 46af5aa363..bd51913552 100644
--- a/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c
+++ b/usr/src/lib/smbsrv/libmlrpc/common/ndr_server.c
@@ -407,7 +407,6 @@ ndr_pipe_grow(ndr_pipe_t *np, size_t desired)
np->np_iov.iov_base = np->np_buf + np->np_uio.uio_offset;
np->np_uio.uio_resid += desired;
np->np_iov.iov_len += desired;
- smb_tracef("ndr_pipe_grow: %d bytes", required);
return (0);
}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h b/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h
index 03603a61aa..6f79f20a1a 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h
+++ b/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h
@@ -277,9 +277,11 @@ void smb_quota_free(smb_quota_response_t *);
uint32_t dfs_get_referrals(const char *, dfs_reftype_t, dfs_info_t *);
void dfs_info_free(dfs_info_t *);
-/* spool functions */
-void spoolss_copy_spool_file(smb_inaddr_t *, char *, char *, char *);
-
+/*
+ * The spoolss installable copyfile API.
+ */
+typedef void (*spoolss_copyfile_t)(smb_inaddr_t *, char *, char *, char *);
+void spoolss_register_copyfile(spoolss_copyfile_t);
#ifdef __cplusplus
}
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/lsar_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/lsar_svc.c
index 652164bce1..e04ef02503 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/lsar_svc.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/lsar_svc.c
@@ -786,6 +786,7 @@ lsarpc_s_LookupNames(void *arg, ndr_xa_t *mxa)
*
* On success return 0. Otherwise return an RPC specific error code.
*/
+
static int
lsarpc_s_LookupSids(void *arg, ndr_xa_t *mxa)
{
@@ -797,20 +798,22 @@ lsarpc_s_LookupSids(void *arg, ndr_xa_t *mxa)
smb_account_t account;
smb_sid_t *sid;
DWORD n_entry;
+ DWORD n_mapped;
+ char sidstr[SMB_SID_STRSZ];
int result;
int i;
+ bzero(&account, sizeof (smb_account_t));
+ n_mapped = 0;
n_entry = param->lup_sid_table.n_entry;
+
names = NDR_NEWN(mxa, struct mslsa_name_entry, n_entry);
domain_table = NDR_NEW(mxa, struct mslsa_domain_table);
domain_entry = NDR_NEWN(mxa, struct mslsa_domain_entry,
MLSVC_DOMAIN_MAX);
- if (names == NULL || domain_table == NULL || domain_entry == NULL) {
- bzero(param, sizeof (struct mslsa_LookupSids));
- param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
- return (NDR_DRC_OK);
- }
+ if (names == NULL || domain_table == NULL || domain_entry == NULL)
+ goto lookup_sid_failed;
domain_table->entries = domain_entry;
domain_table->n_entry = 0;
@@ -818,29 +821,33 @@ lsarpc_s_LookupSids(void *arg, ndr_xa_t *mxa)
name = names;
for (i = 0; i < n_entry; ++i, name++) {
- bzero(&names[i], sizeof (struct mslsa_name_entry));
+ bzero(name, sizeof (struct mslsa_name_entry));
sid = (smb_sid_t *)param->lup_sid_table.entries[i].psid;
result = lsa_lookup_sid(sid, &account);
- if (result != NT_STATUS_SUCCESS)
- goto lookup_sid_failed;
+ if ((result != NT_STATUS_SUCCESS) ||
+ (account.a_name == NULL) || (*account.a_name == '\0')) {
+ account.a_type = SidTypeUnknown;
+ smb_sid_tostr(sid, sidstr);
+
+ if (NDR_MSTRING(mxa, sidstr,
+ (ndr_mstring_t *)&name->name) == -1)
+ goto lookup_sid_failed;
- if (*account.a_name != '\0') {
+ } else {
if (NDR_MSTRING(mxa, account.a_name,
- (ndr_mstring_t *)&name->name) == -1) {
- result = NT_STATUS_NO_MEMORY;
+ (ndr_mstring_t *)&name->name) == -1)
goto lookup_sid_failed;
- }
+
+ ++n_mapped;
}
+
name->sid_name_use = account.a_type;
result = lsarpc_s_UpdateDomainTable(mxa, &account,
domain_table, &name->domain_ix);
-
- if (result == -1) {
- result = NT_STATUS_INTERNAL_ERROR;
+ if (result == -1)
goto lookup_sid_failed;
- }
smb_account_free(&account);
}
@@ -848,20 +855,21 @@ lsarpc_s_LookupSids(void *arg, ndr_xa_t *mxa)
param->domain_table = domain_table;
param->name_table.n_entry = n_entry;
param->name_table.entries = names;
- param->mapped_count = n_entry;
- param->status = 0;
+ param->mapped_count = n_mapped;
+
+ if (n_mapped == n_entry)
+ param->status = NT_STATUS_SUCCESS;
+ else if (n_mapped == 0)
+ param->status = NT_STATUS_NONE_MAPPED;
+ else
+ param->status = NT_STATUS_SOME_NOT_MAPPED;
return (NDR_DRC_OK);
lookup_sid_failed:
- param->domain_table = 0;
- param->name_table.n_entry = 0;
- param->name_table.entries = 0;
- param->mapped_count = 0;
- param->status = NT_SC_ERROR(result);
-
smb_account_free(&account);
- return (NDR_DRC_OK);
+ bzero(param, sizeof (struct mslsa_LookupSids));
+ return (NDR_DRC_FAULT_OUT_OF_MEMORY);
}
/*
@@ -942,20 +950,22 @@ lsarpc_s_LookupSids2(void *arg, ndr_xa_t *mxa)
smb_account_t account;
smb_sid_t *sid;
DWORD n_entry;
+ DWORD n_mapped;
+ char sidstr[SMB_SID_STRSZ];
int result;
int i;
+ bzero(&account, sizeof (smb_account_t));
+ n_mapped = 0;
n_entry = param->lup_sid_table.n_entry;
+
names = NDR_NEWN(mxa, struct lsar_name_entry2, n_entry);
domain_table = NDR_NEW(mxa, struct mslsa_domain_table);
domain_entry = NDR_NEWN(mxa, struct mslsa_domain_entry,
MLSVC_DOMAIN_MAX);
- if (names == NULL || domain_table == NULL || domain_entry == NULL) {
- bzero(param, sizeof (struct lsar_lookup_sids2));
- param->status = NT_SC_ERROR(NT_STATUS_NO_MEMORY);
- return (NDR_DRC_OK);
- }
+ if (names == NULL || domain_table == NULL || domain_entry == NULL)
+ goto lookup_sid_failed;
domain_table->entries = domain_entry;
domain_table->n_entry = 0;
@@ -967,25 +977,29 @@ lsarpc_s_LookupSids2(void *arg, ndr_xa_t *mxa)
sid = (smb_sid_t *)param->lup_sid_table.entries[i].psid;
result = lsa_lookup_sid(sid, &account);
- if (result != NT_STATUS_SUCCESS)
- goto lookup_sid_failed;
+ if ((result != NT_STATUS_SUCCESS) ||
+ (account.a_name == NULL) || (*account.a_name == '\0')) {
+ account.a_type = SidTypeUnknown;
+ smb_sid_tostr(sid, sidstr);
+
+ if (NDR_MSTRING(mxa, sidstr,
+ (ndr_mstring_t *)&name->name) == -1)
+ goto lookup_sid_failed;
- if (*account.a_name != '\0') {
+ } else {
if (NDR_MSTRING(mxa, account.a_name,
- (ndr_mstring_t *)&name->name) == -1) {
- result = NT_STATUS_NO_MEMORY;
+ (ndr_mstring_t *)&name->name) == -1)
goto lookup_sid_failed;
- }
+
+ ++n_mapped;
}
+
name->sid_name_use = account.a_type;
result = lsarpc_s_UpdateDomainTable(mxa, &account,
domain_table, &name->domain_ix);
-
- if (result == -1) {
- result = NT_STATUS_INTERNAL_ERROR;
+ if (result == -1)
goto lookup_sid_failed;
- }
smb_account_free(&account);
}
@@ -993,20 +1007,21 @@ lsarpc_s_LookupSids2(void *arg, ndr_xa_t *mxa)
param->domain_table = domain_table;
param->name_table.n_entry = n_entry;
param->name_table.entries = names;
- param->mapped_count = n_entry;
- param->status = 0;
+ param->mapped_count = n_mapped;
+
+ if (n_mapped == n_entry)
+ param->status = NT_STATUS_SUCCESS;
+ else if (n_mapped == 0)
+ param->status = NT_STATUS_NONE_MAPPED;
+ else
+ param->status = NT_STATUS_SOME_NOT_MAPPED;
return (NDR_DRC_OK);
lookup_sid_failed:
- param->domain_table = 0;
- param->name_table.n_entry = 0;
- param->name_table.entries = 0;
- param->mapped_count = 0;
- param->status = NT_SC_ERROR(result);
-
smb_account_free(&account);
- return (NDR_DRC_OK);
+ bzero(param, sizeof (struct lsar_lookup_sids2));
+ return (NDR_DRC_FAULT_OUT_OF_MEMORY);
}
/*
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers b/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers
index bb9cd09573..29af98f2ac 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mapfile-vers
@@ -76,7 +76,7 @@ SYMBOL_VERSION SUNWprivate {
smb_shr_stop;
smb_token_destroy;
smb_token_log;
- spoolss_copy_spool_file;
+ spoolss_register_copyfile;
local:
*;
};
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h
index 3275133375..8a5d55785b 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h
+++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc.h
@@ -25,7 +25,6 @@
#ifndef _SMBSRV_MLSVC_H
#define _SMBSRV_MLSVC_H
-#include <cups/cups.h>
#include <smbsrv/smb_share.h>
#include <smbsrv/ndl/netlogon.ndl>
@@ -80,26 +79,6 @@ void smb_quota_fini(void);
void smb_quota_add_fs(const char *);
void smb_quota_remove_fs(const char *);
-typedef struct smb_cups_ops {
- void *cups_hdl;
- cups_lang_t *(*cupsLangDefault)();
- const char *(*cupsLangEncoding)(cups_lang_t *);
- void (*cupsLangFree)(cups_lang_t *);
- ipp_status_t (*cupsLastError)();
- int (*cupsGetDests)(cups_dest_t **);
- void (*cupsFreeDests)(int, cups_dest_t *);
- ipp_t *(*cupsDoFileRequest)(http_t *, ipp_t *, const char *,
- const char *);
- ipp_t *(*ippNew)();
- void (*ippDelete)();
- char *(*ippErrorString)();
- ipp_attribute_t *(*ippAddString)();
- void (*httpClose)(http_t *);
- http_t *(*httpConnect)(const char *, int);
-} smb_cups_ops_t;
-
-smb_cups_ops_t *spoolss_cups_ops(void);
-
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c b/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c
index 8b70febc10..5f62c02e51 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c
@@ -52,7 +52,6 @@
#include <smbsrv/smb.h>
#include <mlsvc.h>
#include <dfs.h>
-#include <cups/cups.h>
#define SMB_SHR_ERROR_THRESHOLD 3
#define SMB_SHR_CSC_BUFSZ 64
@@ -139,12 +138,10 @@ static boolean_t smb_shr_is_dot_or_dotdot(const char *);
/*
* sharemgr functions
*/
-static void *smb_shr_sa_loadall(void *);
static void smb_shr_sa_loadgrp(sa_group_t);
static uint32_t smb_shr_sa_load(sa_share_t, sa_resource_t);
static uint32_t smb_shr_sa_loadbyname(char *);
static uint32_t smb_shr_sa_get(sa_share_t, sa_resource_t, smb_share_t *);
-static void smb_shr_load_cups_printers();
/*
* .ZFS management functions
@@ -312,30 +309,6 @@ smb_shr_sa_exit(void)
}
/*
- * Launches a thread to populate the share cache by share information
- * stored in sharemgr
- */
-int
-smb_shr_load(void)
-{
- pthread_t load_thr;
- pthread_attr_t tattr;
- int rc;
-
- (void) pthread_attr_init(&tattr);
- (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
- rc = pthread_create(&load_thr, &tattr, smb_shr_sa_loadall, 0);
- (void) pthread_attr_destroy(&tattr);
-
- (void) mutex_lock(&smb_shr_exec_mtx);
- (void) smb_config_get_execinfo(smb_shr_exec_map, smb_shr_exec_unmap,
- MAXPATHLEN);
- (void) mutex_unlock(&smb_shr_exec_mtx);
-
- return (rc);
-}
-
-/*
* Return the total number of shares
*/
int
@@ -1458,17 +1431,21 @@ smb_shr_cache_freent(HT_ITEM *item)
* Load shares from sharemgr
*/
/*ARGSUSED*/
-static void *
-smb_shr_sa_loadall(void *args)
+void *
+smb_shr_load(void *args)
{
sa_handle_t handle;
sa_group_t group, subgroup;
char *gstate;
boolean_t gdisabled;
- boolean_t printing_enabled;
+
+ (void) mutex_lock(&smb_shr_exec_mtx);
+ (void) smb_config_get_execinfo(smb_shr_exec_map, smb_shr_exec_unmap,
+ MAXPATHLEN);
+ (void) mutex_unlock(&smb_shr_exec_mtx);
if ((handle = smb_shr_sa_enter()) == NULL) {
- syslog(LOG_ERR, "smb_shr_sa_loadall: ret NULL");
+ syslog(LOG_ERR, "smb_shr_load: load failed");
return (NULL);
}
@@ -1493,53 +1470,10 @@ smb_shr_sa_loadall(void *args)
}
smb_shr_sa_exit();
- printing_enabled = smb_config_getbool(SMB_CI_PRINT_ENABLE);
- if (printing_enabled)
- smb_shr_load_cups_printers();
return (NULL);
}
/*
- * Load print shares from cups
- */
-static void
-smb_shr_load_cups_printers()
-{
- uint32_t nerr;
- int i;
- cups_dest_t *dests;
- int num_dests;
- cups_dest_t *dest;
- smb_share_t si;
- smb_cups_ops_t *cups;
-
- if ((cups = spoolss_cups_ops()) == NULL)
- return;
-
- if (smb_shr_get(SMB_SHARE_PRINT, &si) != NERR_Success) {
- syslog(LOG_DEBUG, "error getting print$");
- return;
- }
-
- num_dests = cups->cupsGetDests(&dests);
- for (i = num_dests, dest = dests; i > 0; i--, dest++) {
- if (dest->instance == NULL) {
- /*
- * Use the path from print$
- */
- (void) strlcpy(si.shr_name, dest->name, MAXPATHLEN);
- (void) strlcpy(si.shr_cmnt,
- SMB_SHARE_PRINT, SMB_SHARE_PRINT_LEN + 1);
- si.shr_type = STYPE_PRINTQ;
- nerr = smb_shr_add(&si);
- if (nerr != NERR_Success)
- break;
- }
- }
- cups->cupsFreeDests(num_dests, dests);
-}
-
-/*
* Load the shares contained in the specified group.
*
* Don't process groups on which the smb protocol is disabled.
diff --git a/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c b/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c
index 8630e5d10c..d0fc9aa4ab 100644
--- a/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c
+++ b/usr/src/lib/smbsrv/libmlsvc/common/spoolss_svc.c
@@ -25,62 +25,61 @@
/*
* Printing and Spooling RPC service.
*/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/utsname.h>
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
-#include <pthread.h>
-#include <synch.h>
+#include <fcntl.h>
+#include <errno.h>
#include <smbsrv/libsmb.h>
#include <smbsrv/libmlrpc.h>
#include <smbsrv/libmlsvc.h>
-#include <smbsrv/ndl/ndrtypes.ndl>
+#include <smbsrv/smb.h>
#include <smbsrv/ndl/spoolss.ndl>
+#include <smbsrv/ndl/winreg.ndl>
#include <smb/nterror.h>
#include <smbsrv/smbinfo.h>
#include <smbsrv/nmpipes.h>
-#include <wchar.h>
-#include <cups/cups.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <dlfcn.h>
#include <mlsvc.h>
+#define SPOOLSS_PRINTER "Postscript"
+
typedef struct smb_spool {
- list_t sp_list;
- int sp_cnt;
- rwlock_t sp_rwl;
- int sp_initialized;
+ list_t sp_list;
+ int sp_cnt;
+ rwlock_t sp_rwl;
+ int sp_initialized;
} smb_spool_t;
+typedef struct smb_spooldoc {
+ uint32_t sd_magic;
+ list_node_t sd_lnd;
+ smb_inaddr_t sd_ipaddr;
+ int sd_spool_num;
+ char sd_username[MAXNAMELEN];
+ char sd_path[MAXPATHLEN];
+ char sd_doc_name[MAXNAMELEN];
+ char sd_printer_name[MAXPATHLEN];
+ int32_t sd_fd;
+ ndr_hdid_t sd_handle;
+} smb_spooldoc_t;
+
+typedef struct {
+ char *name;
+ uint32_t value;
+} spoolss_winreg_t;
+
+typedef struct {
+ uint8_t *sd_buf;
+ uint32_t sd_size;
+} spoolss_sd_t;
+
static uint32_t spoolss_cnt;
-static uint32_t spoolss_jobnum = 1;
static smb_spool_t spoolss_splist;
-static smb_cups_ops_t smb_cups;
-static mutex_t spoolss_cups_mutex;
-#define SPOOLSS_PJOBLEN 256
-#define SPOOLSS_JOB_NOT_ISSUED 3004
-#define SPOOLSS_PRINTER "Postscript"
-#define SPOOLSS_FN_PREFIX "cifsprintjob-"
-#define SPOOLSS_CUPS_SPOOL_DIR "//var//spool//cups"
-
-struct spoolss_printjob {
- pid_t pj_pid;
- int pj_sysjob;
- int pj_fd;
- time_t pj_start_time;
- int pj_status;
- size_t pj_size;
- int pj_page_count;
- boolean_t pj_isspooled;
- boolean_t pj_jobnum;
- char pj_filename[SPOOLSS_PJOBLEN];
- char pj_jobname[SPOOLSS_PJOBLEN];
- char pj_username[SPOOLSS_PJOBLEN];
- char pj_queuename[SPOOLSS_PJOBLEN];
-};
+void (*spoolss_copyfile_callback)(smb_inaddr_t *, char *, char *, char *);
DECL_FIXUP_STRUCT(spoolss_GetPrinter_result_u);
DECL_FIXUP_STRUCT(spoolss_GetPrinter_result);
@@ -92,13 +91,10 @@ DECL_FIXUP_STRUCT(spoolss_RPC_V2_NOTIFY_INFO);
DECL_FIXUP_STRUCT(spoolss_RFNPCNEX);
uint32_t srvsvc_sd_set_relative(smb_sd_t *, uint8_t *);
-static int spoolss_s_make_sd(uint8_t *);
-static uint32_t spoolss_sd_format(smb_sd_t *);
-static int spoolss_find_fd(ndr_hdid_t *);
-static void spoolss_find_doc_and_print(ndr_hdid_t *);
-static void spoolss_add_spool_doc(smb_spooldoc_t *);
-static int spoolss_cups_init(void);
-static void spoolss_cups_fini(void);
+static int spoolss_getservername(char *, size_t);
+static uint32_t spoolss_make_sd(ndr_xa_t *, spoolss_sd_t *);
+static uint32_t spoolss_format_sd(smb_sd_t *);
+static int spoolss_find_document(ndr_hdid_t *);
static int spoolss_s_OpenPrinter(void *, ndr_xa_t *);
static int spoolss_s_ClosePrinter(void *, ndr_xa_t *);
@@ -116,7 +112,14 @@ static int spoolss_s_StartPagePrinter(void *, ndr_xa_t *);
static int spoolss_s_EndPagePrinter(void *, ndr_xa_t *);
static int spoolss_s_rfnpcnex(void *, ndr_xa_t *);
static int spoolss_s_WritePrinter(void *, ndr_xa_t *);
+static int spoolss_s_AddForm(void *, ndr_xa_t *);
+static int spoolss_s_DeleteForm(void *, ndr_xa_t *);
static int spoolss_s_EnumForms(void *, ndr_xa_t *);
+static int spoolss_s_AddMonitor(void *, ndr_xa_t *);
+static int spoolss_s_DeleteMonitor(void *, ndr_xa_t *);
+static int spoolss_s_DeletePort(void *, ndr_xa_t *);
+static int spoolss_s_AddPortEx(void *, ndr_xa_t *);
+static int spoolss_s_SetPort(void *, ndr_xa_t *);
static int spoolss_s_stub(void *, ndr_xa_t *);
static ndr_stub_table_t spoolss_stub_table[] = {
@@ -138,7 +141,14 @@ static ndr_stub_table_t spoolss_stub_table[] = {
{ spoolss_s_ScheduleJob, SPOOLSS_OPNUM_ScheduleJob },
{ spoolss_s_GetPrinterData, SPOOLSS_OPNUM_GetPrinterData },
{ spoolss_s_ClosePrinter, SPOOLSS_OPNUM_ClosePrinter },
+ { spoolss_s_AddForm, SPOOLSS_OPNUM_AddForm },
+ { spoolss_s_DeleteForm, SPOOLSS_OPNUM_DeleteForm },
{ spoolss_s_EnumForms, SPOOLSS_OPNUM_EnumForms },
+ { spoolss_s_AddMonitor, SPOOLSS_OPNUM_AddMonitor },
+ { spoolss_s_DeleteMonitor, SPOOLSS_OPNUM_DeleteMonitor },
+ { spoolss_s_DeletePort, SPOOLSS_OPNUM_DeletePort },
+ { spoolss_s_AddPortEx, SPOOLSS_OPNUM_AddPortEx },
+ { spoolss_s_SetPort, SPOOLSS_OPNUM_SetPort },
{ spoolss_s_stub, SPOOLSS_OPNUM_GetPrinterDriver2 },
{ spoolss_s_stub, SPOOLSS_OPNUM_FCPN },
{ spoolss_s_stub, SPOOLSS_OPNUM_ReplyOpenPrinter },
@@ -168,32 +178,66 @@ static ndr_service_t spoolss_service = {
spoolss_stub_table /* stub_table */
};
-/*
- * Defer calling spoolss_cups_init() until something actually
- * needs access to CUPS due to the libcups dependency on OpenSSL.
- * OpenSSL is not MT-safe and initializing CUPS here can crash
- * OpenSSL if it collides with other threads that are in other
- * libraries that are attempting to use OpenSSL.
- */
void
spoolss_initialize(void)
{
+ if (!spoolss_splist.sp_initialized) {
+ list_create(&spoolss_splist.sp_list,
+ sizeof (smb_spooldoc_t),
+ offsetof(smb_spooldoc_t, sd_lnd));
+ spoolss_splist.sp_initialized = 1;
+ }
+
+ spoolss_copyfile_callback = NULL;
+
(void) ndr_svc_register(&spoolss_service);
}
void
spoolss_finalize(void)
{
- spoolss_cups_fini();
+ spoolss_copyfile_callback = NULL;
+}
+
+/*
+ * Register a copyfile callback that the spoolss service can use to
+ * copy files to the spool directory.
+ *
+ * Set a null pointer to disable the copying of files to the spool
+ * directory.
+ */
+void
+spoolss_register_copyfile(spoolss_copyfile_t copyfile)
+{
+ spoolss_copyfile_callback = copyfile;
+}
+
+static void
+spoolss_copyfile(smb_inaddr_t *ipaddr, char *username, char *path,
+ char *docname)
+{
+ if (spoolss_copyfile_callback != NULL)
+ (*spoolss_copyfile_callback)(ipaddr, username, path, docname);
}
static int
spoolss_s_OpenPrinter(void *arg, ndr_xa_t *mxa)
{
struct spoolss_OpenPrinter *param = arg;
- ndr_hdid_t *id;
+ char *name = (char *)param->printer_name;
+ ndr_hdid_t *id;
+
+ if (name != NULL && *name != '\0') {
+ if (strspn(name, "\\") > 2) {
+ bzero(&param->handle, sizeof (spoolss_handle_t));
+ param->status = ERROR_INVALID_PRINTER_NAME;
+ return (NDR_DRC_OK);
+ }
+
+ smb_tracef("spoolss_s_OpenPrinter: %s", name);
+ }
- if ((id = ndr_hdalloc(mxa, 0)) == NULL) {
+ if ((id = ndr_hdalloc(mxa, NULL)) == NULL) {
bzero(&param->handle, sizeof (spoolss_handle_t));
param->status = ERROR_NOT_ENOUGH_MEMORY;
return (NDR_DRC_OK);
@@ -201,7 +245,6 @@ spoolss_s_OpenPrinter(void *arg, ndr_xa_t *mxa)
bcopy(id, &param->handle, sizeof (spoolss_handle_t));
param->status = 0;
-
return (NDR_DRC_OK);
}
@@ -228,99 +271,9 @@ spoolss_s_EndPagePrinter(void *arg, ndr_xa_t *mxa)
}
/*
- *
- * adds new spool doc to the tail. used by windows
- * XP and 2000 only
- *
- * Return values
- * smb_spooldoc_t - NULL if not found
- */
-
-static void
-spoolss_add_spool_doc(smb_spooldoc_t *sp)
-{
- (void) rw_wrlock(&spoolss_splist.sp_rwl);
- if (!spoolss_splist.sp_initialized) {
- list_create(&spoolss_splist.sp_list,
- sizeof (smb_spooldoc_t),
- offsetof(smb_spooldoc_t, sd_lnd));
- spoolss_splist.sp_initialized = 1;
- }
- list_insert_tail(&spoolss_splist.sp_list, sp);
- spoolss_splist.sp_cnt++;
- (void) rw_unlock(&spoolss_splist.sp_rwl);
-}
-
-/*
- *
- * finds a completed spool doc using the RPC handle
- * as the key, then prints the doc
- *
- * XP and 2000 only
- *
- */
-
-static void
-spoolss_find_doc_and_print(ndr_hdid_t *handle)
-{
- smb_spooldoc_t *sp;
-
- if (!spoolss_splist.sp_initialized) {
- syslog(LOG_ERR, "spoolss_find_doc_and_print: not initialized");
- return;
- }
- (void) rw_wrlock(&spoolss_splist.sp_rwl);
- sp = list_head(&spoolss_splist.sp_list);
- while (sp != NULL) {
- /*
- * search the spooldoc list for a matching RPC handle
- * and use the info to pass to cups for printing
- */
- if (!memcmp(handle, &(sp->sd_handle), sizeof (ndr_hdid_t))) {
- spoolss_copy_spool_file(&sp->sd_ipaddr,
- sp->sd_username, sp->sd_path, sp->sd_doc_name);
- (void) close(sp->sd_fd);
- list_remove(&spoolss_splist.sp_list, sp);
- free(sp);
- (void) rw_unlock(&spoolss_splist.sp_rwl);
- return;
- }
- sp = list_next(&spoolss_splist.sp_list, sp);
- }
- syslog(LOG_ERR, "spoolss_find_doc_and_print: handle not found");
- (void) rw_unlock(&spoolss_splist.sp_rwl);
-}
-
-static int
-spoolss_find_fd(ndr_hdid_t *handle)
-{
- smb_spooldoc_t *sp;
-
- if (!spoolss_splist.sp_initialized) {
- syslog(LOG_ERR, "spoolss_find_fd: not initialized");
- return (-1);
- }
- (void) rw_rdlock(&spoolss_splist.sp_rwl);
- sp = list_head(&spoolss_splist.sp_list);
- while (sp != NULL) {
- /*
- * check for a matching rpc handle in the
- * spooldoc list
- */
- if (!memcmp(handle, &(sp->sd_handle), sizeof (ndr_hdid_t))) {
- (void) rw_unlock(&spoolss_splist.sp_rwl);
- return (sp->sd_fd);
- }
- sp = list_next(&spoolss_splist.sp_list, sp);
- }
- syslog(LOG_ERR, "spoolss_find_fd: handle not found");
- (void) rw_unlock(&spoolss_splist.sp_rwl);
- return (-1);
-}
-
-/*
* Windows XP and 2000 use this mechanism to write spool files.
- * Creates a spool file fd to be used by spoolss_s_WritePrinter.
+ * Create a spool file fd to be used by spoolss_s_WritePrinter
+ * and add it to the tail of the spool list.
*/
static int
spoolss_s_StartDocPrinter(void *arg, ndr_xa_t *mxa)
@@ -335,7 +288,7 @@ spoolss_s_StartDocPrinter(void *arg, ndr_xa_t *mxa)
int fd;
if (ndr_hdlookup(mxa, id) == NULL) {
- syslog(LOG_ERR, "spoolss_s_StartDocPrinter: invalid handle");
+ smb_tracef("spoolss_s_StartDocPrinter: invalid handle");
param->status = ERROR_INVALID_HANDLE;
return (NDR_DRC_OK);
}
@@ -346,7 +299,7 @@ spoolss_s_StartDocPrinter(void *arg, ndr_xa_t *mxa)
}
if ((rc = smb_shr_get(SMB_SHARE_PRINT, &si)) != NERR_Success) {
- syslog(LOG_INFO, "spoolss_s_StartDocPrinter: %s error=%d",
+ smb_tracef("spoolss_s_StartDocPrinter: %s error=%d",
SMB_SHARE_PRINT, rc);
param->status = rc;
return (NDR_DRC_OK);
@@ -372,8 +325,8 @@ spoolss_s_StartDocPrinter(void *arg, ndr_xa_t *mxa)
spfile->sd_ipaddr = mxa->pipe->np_user.ui_ipaddr;
(void) strlcpy((char *)spfile->sd_username,
mxa->pipe->np_user.ui_account, MAXNAMELEN);
- (void) memcpy(&spfile->sd_handle, &param->handle,
- sizeof (rpc_handle_t));
+ (void) memcpy(&spfile->sd_handle, &param->handle, sizeof (ndr_hdid_t));
+
/*
* write temporary spool file to print$
*/
@@ -383,14 +336,22 @@ spoolss_s_StartDocPrinter(void *arg, ndr_xa_t *mxa)
fd = open(g_path, O_CREAT | O_RDWR, 0600);
if (fd == -1) {
- syslog(LOG_INFO, "spoolss_s_StartDocPrinter: %s: %s",
+ smb_tracef("spoolss_s_StartDocPrinter: %s: %s",
g_path, strerror(errno));
param->status = ERROR_OPEN_FAILED;
free(spfile);
} else {
(void) strlcpy((char *)spfile->sd_path, g_path, MAXPATHLEN);
spfile->sd_fd = (uint16_t)fd;
- spoolss_add_spool_doc(spfile);
+
+ /*
+ * Add the document to the spool list.
+ */
+ (void) rw_wrlock(&spoolss_splist.sp_rwl);
+ list_insert_tail(&spoolss_splist.sp_list, spfile);
+ spoolss_splist.sp_cnt++;
+ (void) rw_unlock(&spoolss_splist.sp_rwl);
+
/*
* JobId isn't used now, but if printQ management is added
* this will have to be incremented per job submitted.
@@ -403,16 +364,44 @@ spoolss_s_StartDocPrinter(void *arg, ndr_xa_t *mxa)
/*
* Windows XP and 2000 use this mechanism to write spool files
+ * Search the spooldoc list for a matching RPC handle and pass
+ * the spool the file for printing.
*/
-
-/*ARGSUSED*/
static int
spoolss_s_EndDocPrinter(void *arg, ndr_xa_t *mxa)
{
struct spoolss_EndDocPrinter *param = arg;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
+ smb_spooldoc_t *sp;
- spoolss_find_doc_and_print((ndr_hdid_t *)&param->handle);
- param->status = ERROR_SUCCESS;
+ if (ndr_hdlookup(mxa, id) == NULL) {
+ smb_tracef("spoolss_s_EndDocPrinter: invalid handle");
+ param->status = ERROR_INVALID_HANDLE;
+ return (NDR_DRC_OK);
+ }
+
+ param->status = ERROR_INVALID_HANDLE;
+ (void) rw_wrlock(&spoolss_splist.sp_rwl);
+
+ sp = list_head(&spoolss_splist.sp_list);
+ while (sp != NULL) {
+ if (!memcmp(id, &(sp->sd_handle), sizeof (ndr_hdid_t))) {
+ spoolss_copyfile(&sp->sd_ipaddr,
+ sp->sd_username, sp->sd_path, sp->sd_doc_name);
+ (void) close(sp->sd_fd);
+ list_remove(&spoolss_splist.sp_list, sp);
+ free(sp);
+ param->status = ERROR_SUCCESS;
+ break;
+ }
+
+ sp = list_next(&spoolss_splist.sp_list, sp);
+ }
+
+ (void) rw_unlock(&spoolss_splist.sp_rwl);
+
+ if (param->status != ERROR_SUCCESS)
+ smb_tracef("spoolss_s_EndDocPrinter: document not found");
return (NDR_DRC_OK);
}
@@ -440,8 +429,8 @@ static int
spoolss_s_ClosePrinter(void *arg, ndr_xa_t *mxa)
{
struct spoolss_ClosePrinter *param = arg;
- ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
- ndr_handle_t *hd;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
+ ndr_handle_t *hd;
if ((hd = ndr_hdlookup(mxa, id)) != NULL) {
free(hd->nh_data);
@@ -454,20 +443,110 @@ spoolss_s_ClosePrinter(void *arg, ndr_xa_t *mxa)
return (NDR_DRC_OK);
}
-/*ARGSUSED*/
-int
+static int
+spoolss_s_AddForm(void *arg, ndr_xa_t *mxa)
+{
+ struct spoolss_AddForm *param = arg;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
+
+ if (ndr_hdlookup(mxa, id) == NULL) {
+ bzero(param, sizeof (struct spoolss_AddForm));
+ param->status = ERROR_INVALID_HANDLE;
+ return (NDR_DRC_OK);
+ }
+
+ bzero(param, sizeof (struct spoolss_AddForm));
+ param->status = ERROR_SUCCESS;
+ return (NDR_DRC_OK);
+}
+
+static int
+spoolss_s_DeleteForm(void *arg, ndr_xa_t *mxa)
+{
+ struct spoolss_DeleteForm *param = arg;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
+
+ if (ndr_hdlookup(mxa, id) == NULL) {
+ bzero(param, sizeof (struct spoolss_DeleteForm));
+ param->status = ERROR_INVALID_HANDLE;
+ return (NDR_DRC_OK);
+ }
+
+ bzero(param, sizeof (struct spoolss_DeleteForm));
+ param->status = ERROR_SUCCESS;
+ return (NDR_DRC_OK);
+}
+
+static int
spoolss_s_EnumForms(void *arg, ndr_xa_t *mxa)
{
struct spoolss_EnumForms *param = arg;
- DWORD status = ERROR_SUCCESS;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
- param->status = status;
+ if (ndr_hdlookup(mxa, id) == NULL) {
+ bzero(param, sizeof (struct spoolss_EnumForms));
+ param->status = ERROR_INVALID_HANDLE;
+ return (NDR_DRC_OK);
+ }
+
+ bzero(param, sizeof (struct spoolss_EnumForms));
+ param->status = ERROR_SUCCESS;
param->needed = 0;
return (NDR_DRC_OK);
}
/*ARGSUSED*/
-int
+static int
+spoolss_s_AddMonitor(void *arg, ndr_xa_t *mxa)
+{
+ struct spoolss_AddMonitor *param = arg;
+
+ param->status = ERROR_SUCCESS;
+ return (NDR_DRC_OK);
+}
+
+/*ARGSUSED*/
+static int
+spoolss_s_DeleteMonitor(void *arg, ndr_xa_t *mxa)
+{
+ struct spoolss_DeleteMonitor *param = arg;
+
+ param->status = ERROR_SUCCESS;
+ return (NDR_DRC_OK);
+}
+
+/*ARGSUSED*/
+static int
+spoolss_s_DeletePort(void *arg, ndr_xa_t *mxa)
+{
+ struct spoolss_DeletePort *param = arg;
+
+ param->status = ERROR_SUCCESS;
+ return (NDR_DRC_OK);
+}
+
+/*ARGSUSED*/
+static int
+spoolss_s_AddPortEx(void *arg, ndr_xa_t *mxa)
+{
+ struct spoolss_AddPortEx *param = arg;
+
+ param->status = ERROR_SUCCESS;
+ return (NDR_DRC_OK);
+}
+
+/*ARGSUSED*/
+static int
+spoolss_s_SetPort(void *arg, ndr_xa_t *mxa)
+{
+ struct spoolss_SetPort *param = arg;
+
+ param->status = ERROR_SUCCESS;
+ return (NDR_DRC_OK);
+}
+
+/*ARGSUSED*/
+static int
spoolss_s_EnumJobs(void *arg, ndr_xa_t *mxa)
{
struct spoolss_EnumJobs *param = arg;
@@ -510,7 +589,7 @@ static int
spoolss_s_ScheduleJob(void *arg, ndr_xa_t *mxa)
{
struct spoolss_ScheduleJob *param = arg;
- DWORD status = SPOOLSS_JOB_NOT_ISSUED;
+ DWORD status = ERROR_SPL_NO_ADDJOB;
param->status = status;
return (NDR_DRC_OK);
@@ -552,20 +631,20 @@ spoolss_s_WritePrinter(void *arg, ndr_xa_t *mxa)
if (ndr_hdlookup(mxa, id) == NULL) {
param->written = 0;
param->status = ERROR_INVALID_HANDLE;
- syslog(LOG_ERR, "spoolss_s_WritePrinter: invalid handle");
+ smb_tracef("spoolss_s_WritePrinter: invalid handle");
return (NDR_DRC_OK);
}
- if ((spfd = spoolss_find_fd(id)) < 0) {
+ if ((spfd = spoolss_find_document(id)) < 0) {
param->written = 0;
param->status = ERROR_INVALID_HANDLE;
- syslog(LOG_ERR, "spoolss_s_WritePrinter: cannot find fd");
+ smb_tracef("spoolss_s_WritePrinter: document not found");
return (NDR_DRC_OK);
}
written = write(spfd, param->pBuf, param->BufCount);
if (written < param->BufCount) {
- syslog(LOG_ERR, "spoolss_s_WritePrinter: write failed");
+ smb_tracef("spoolss_s_WritePrinter: write failed");
param->written = 0;
param->status = ERROR_CANTWRITE;
return (NDR_DRC_OK);
@@ -577,274 +656,182 @@ spoolss_s_WritePrinter(void *arg, ndr_xa_t *mxa)
}
/*
- * All versions of windows use this function to print
- * spool files via the cups interface
+ * Find a document by RPC handle in the spool list and return the fd.
*/
-
-void
-spoolss_copy_spool_file(smb_inaddr_t *ipaddr, char *username,
- char *path, char *doc_name)
+static int
+spoolss_find_document(ndr_hdid_t *handle)
{
- smb_cups_ops_t *cups;
- int ret = 1; /* Return value */
- http_t *http = NULL; /* HTTP connection to server */
- ipp_t *request = NULL; /* IPP Request */
- ipp_t *response = NULL; /* IPP Response */
- cups_lang_t *language = NULL; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- char new_jobname[SPOOLSS_PJOBLEN];
- struct spoolss_printjob pjob;
- char clientname[INET6_ADDRSTRLEN];
- struct stat sbuf;
-
- if (stat(path, &sbuf)) {
- syslog(LOG_INFO, "spoolss_copy_spool_file: %s: %s",
- path, strerror(errno));
- return;
- }
-
- /*
- * Remove zero size files and return; these were inadvertantly
- * created by XP or 2000.
- */
- if (sbuf.st_blocks == 0) {
- if (remove(path))
- syslog(LOG_INFO,
- "spoolss_copy_spool_file: cannot remove %s", path);
- return;
- }
-
- if ((cups = spoolss_cups_ops()) == NULL)
- return;
+ smb_spooldoc_t *sp;
- if ((http = cups->httpConnect("localhost", 631)) == NULL) {
- syslog(LOG_INFO, "spoolss_copy_spool_file: cupsd not running");
- return;
- }
+ (void) rw_rdlock(&spoolss_splist.sp_rwl);
- if ((request = cups->ippNew()) == NULL) {
- syslog(LOG_INFO, "spoolss_copy_spool_file: ipp not running");
- return;
- }
- request->request.op.operation_id = IPP_PRINT_JOB;
- request->request.op.request_id = 1;
- language = cups->cupsLangDefault();
-
- cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cups->cupsLangEncoding(language));
-
- cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- (void) snprintf(uri, sizeof (uri), "ipp://localhost/printers/%s",
- SPOOLSS_PRINTER);
- pjob.pj_pid = pthread_self();
- pjob.pj_sysjob = 10;
- (void) strlcpy(pjob.pj_filename, path, SPOOLSS_PJOBLEN);
- pjob.pj_start_time = time(NULL);
- pjob.pj_status = 2;
- pjob.pj_size = sbuf.st_blocks * 512;
- pjob.pj_page_count = 1;
- pjob.pj_isspooled = B_TRUE;
- pjob.pj_jobnum = spoolss_jobnum;
-
- (void) strlcpy(pjob.pj_jobname, doc_name, SPOOLSS_PJOBLEN);
- (void) strlcpy(pjob.pj_username, username, SPOOLSS_PJOBLEN);
- (void) strlcpy(pjob.pj_queuename, SPOOLSS_CUPS_SPOOL_DIR,
- SPOOLSS_PJOBLEN);
- cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
-
- cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requesting-user-name", NULL, pjob.pj_username);
-
- if (smb_inet_ntop(ipaddr, clientname,
- SMB_IPSTRLEN(ipaddr->a_family)) == NULL) {
- syslog(LOG_INFO, "spoolss_copy_spool_file: %s: unknown client",
- clientname);
- goto out;
- }
- cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "job-originating-host-name", NULL, clientname);
-
- (void) snprintf(new_jobname, SPOOLSS_PJOBLEN, "%s%d",
- SPOOLSS_FN_PREFIX, pjob.pj_jobnum);
- cups->ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "job-name", NULL, new_jobname);
-
- (void) snprintf(uri, sizeof (uri) - 1, "/printers/%s", SPOOLSS_PRINTER);
-
- response = cups->cupsDoFileRequest(http, request, uri,
- pjob.pj_filename);
- if (response != NULL) {
- if (response->request.status.status_code >= IPP_OK_CONFLICT) {
- syslog(LOG_ERR,
- "spoolss_copy_spool_file: file print %s: %s",
- SPOOLSS_PRINTER,
- cups->ippErrorString(cups->cupsLastError()));
- } else {
- atomic_inc_32(&spoolss_jobnum);
- ret = 0;
+ sp = list_head(&spoolss_splist.sp_list);
+ while (sp != NULL) {
+ if (!memcmp(handle, &(sp->sd_handle), sizeof (ndr_hdid_t))) {
+ (void) rw_unlock(&spoolss_splist.sp_rwl);
+ return (sp->sd_fd);
}
- } else {
- syslog(LOG_ERR,
- "spoolss_copy_spool_file: unable to print file to %s",
- cups->ippErrorString(cups->cupsLastError()));
+ sp = list_next(&spoolss_splist.sp_list, sp);
}
- if (ret == 0)
- (void) unlink(pjob.pj_filename);
-
-out:
- if (response)
- cups->ippDelete(response);
-
- if (language)
- cups->cupsLangFree(language);
-
- if (http)
- cups->httpClose(http);
+ (void) rw_unlock(&spoolss_splist.sp_rwl);
+ return (-1);
}
+/*
+ * GetPrinterData is used t obtain values from the registry for a
+ * printer or a print server. See [MS-RPRN] for value descriptions.
+ * The registry returns ERROR_FILE_NOT_FOUND for unknown keys.
+ */
static int
spoolss_s_GetPrinterData(void *arg, ndr_xa_t *mxa)
{
- struct spoolss_GetPrinterData *param = arg;
- DWORD status = ERROR_SUCCESS;
+ static spoolss_winreg_t reg[] = {
+ { "ChangeId", 0x0050acf2 },
+ { "W3SvcInstalled", 0x00000000 },
+ { "BeepEnabled", 0x00000000 },
+ { "EventLog", 0x0000001f },
+ { "NetPopup", 0x00000000 },
+ { "NetPopupToComputer", 0x00000000 },
+ { "MajorVersion", 0x00000003 },
+ { "MinorVersion", 0x00000000 },
+ { "DsPresent", 0x00000000 }
+ };
- if (param->Size > 0) {
- param->Buf = NDR_NEWN(mxa, char, param->Size);
- bzero(param->Buf, param->Size);
- } else {
- param->Buf = NDR_NEWN(mxa, uint32_t, 1);
- param->Buf[0] = 1;
- param->Buf[1] = 1;
- param->Buf[2] = 2;
- param->Buf[3] = 2;
+ struct spoolss_GetPrinterData *param = arg;
+ char *name = (char *)param->pValueName;
+ char buf[MAXPATHLEN];
+ static uint8_t reserved_buf[4];
+ spoolss_winreg_t *rp;
+ smb_share_t si;
+ smb_version_t *osversion;
+ struct utsname sysname;
+ smb_wchar_t *wcs;
+ uint32_t value;
+ uint32_t status;
+ int wcslen;
+ int i;
+
+ if (name == NULL || *name == '\0') {
+ status = ERROR_FILE_NOT_FOUND;
+ goto report_error;
}
- /*
- * Increment pType if the Printer Data changes
- * as specified by Microsoft documentation
- */
- param->pType = 1;
- if (strcasecmp((char *)param->pValueName, "ChangeId") == 0) {
- param->pType = 4;
- param->Buf[3] = 0x00;
- param->Buf[2] = 0x50;
- param->Buf[1] = 0xac;
- param->Buf[0] = 0xf2;
- } else if (strcasecmp((char *)param->pValueName,
- "UISingleJobStatusString") == 0) {
- status = ERROR_FILE_NOT_FOUND;
- } else if (strcasecmp((char *)param->pValueName,
- "W3SvcInstalled") == 0) {
- status = ERROR_FILE_NOT_FOUND;
- } else if (strcasecmp((char *)param->pValueName,
- "PrintProcCaps_NT EMF 1.008") == 0) {
- status = ERROR_FILE_NOT_FOUND;
- } else if (strcasecmp((char *)param->pValueName, "OSVersion") == 0) {
- param->Buf = NDR_NEWN(mxa, char, param->Size);
- bzero(param->Buf, param->Size);
- param->Buf[0] = 0x14;
- param->Buf[1] = 0x01;
- param->Buf[4] = 0x05;
- param->Buf[12] = 0x93;
- param->Buf[13] = 0x08;
+ for (i = 0; i < sizeof (reg) / sizeof (reg[0]); ++i) {
+ param->pType = WINREG_DWORD;
+ param->Needed = sizeof (uint32_t);
+ rp = &reg[i];
+
+ if (strcasecmp(name, rp->name) != 0)
+ continue;
+
+ if (param->Size < sizeof (uint32_t)) {
+ param->Size = 0;
+ goto need_more_data;
+ }
+
+ if ((param->Buf = NDR_NEW(mxa, uint32_t)) == NULL) {
+ status = ERROR_NOT_ENOUGH_MEMORY;
+ goto report_error;
+ }
+
+ value = rp->value;
+
+ if ((strcasecmp(name, "DsPresent") == 0) &&
+ (smb_config_get_secmode() == SMB_SECMODE_DOMAIN))
+ value = 0x00000001;
+
+ bcopy(&value, param->Buf, sizeof (uint32_t));
+ param->Size = sizeof (uint32_t);
+ param->status = ERROR_SUCCESS;
+ return (NDR_DRC_OK);
}
- param->status = status;
- param->Needed = param->Size;
- return (NDR_DRC_OK);
-}
-smb_cups_ops_t *
-spoolss_cups_ops(void)
-{
- if (spoolss_cups_init() != 0)
- return (NULL);
+ if (strcasecmp(name, "OSVersion") == 0) {
+ param->pType = WINREG_BINARY;
+ param->Needed = sizeof (smb_version_t);
- return (&smb_cups);
-}
+ if (param->Size < sizeof (smb_version_t)) {
+ param->Size = sizeof (smb_version_t);
+ goto need_more_data;
+ }
-static int
-spoolss_cups_init(void)
-{
- (void) mutex_lock(&spoolss_cups_mutex);
+ if ((osversion = NDR_NEW(mxa, smb_version_t)) == NULL) {
+ status = ERROR_NOT_ENOUGH_MEMORY;
+ goto report_error;
+ }
+
+ smb_config_get_version(osversion);
+ param->Buf = (uint8_t *)osversion;
+ param->status = ERROR_SUCCESS;
+ return (NDR_DRC_OK);
+ }
- if (smb_cups.cups_hdl != NULL) {
- (void) mutex_unlock(&spoolss_cups_mutex);
- return (0);
+ if (strcasecmp(name, "DNSMachineName") == 0) {
+ param->pType = WINREG_SZ;
+ buf[0] = '\0';
+ (void) smb_getfqhostname(buf, MAXHOSTNAMELEN);
+ goto encode_string;
}
- if ((smb_cups.cups_hdl = dlopen("libcups.so.2", RTLD_NOW)) == NULL) {
- (void) mutex_unlock(&spoolss_cups_mutex);
- syslog(LOG_DEBUG, "spoolss_cups_init: cannot open libcups");
- return (ENOENT);
+ if (strcasecmp(name, "DefaultSpoolDirectory") == 0) {
+ param->pType = WINREG_SZ;
+ buf[0] = '\0';
+
+ if (smb_shr_get(SMB_SHARE_PRINT, &si) != NERR_Success) {
+ status = ERROR_FILE_NOT_FOUND;
+ goto report_error;
+ }
+
+ (void) snprintf(buf, MAXPATHLEN, "C:/%s", si.shr_path);
+ (void) strcanon(buf, "/\\");
+ (void) strsubst(buf, '/', '\\');
+ goto encode_string;
}
- smb_cups.cupsLangDefault =
- (cups_lang_t *(*)())dlsym(smb_cups.cups_hdl, "cupsLangDefault");
- smb_cups.cupsLangEncoding = (const char *(*)(cups_lang_t *))
- dlsym(smb_cups.cups_hdl, "cupsLangEncoding");
- smb_cups.cupsDoFileRequest =
- (ipp_t *(*)(http_t *, ipp_t *, const char *, const char *))
- dlsym(smb_cups.cups_hdl, "cupsDoFileRequest");
- smb_cups.cupsLastError = (ipp_status_t (*)())
- dlsym(smb_cups.cups_hdl, "cupsLastError");
- smb_cups.cupsLangFree = (void (*)(cups_lang_t *))
- dlsym(smb_cups.cups_hdl, "cupsLangFree");
- smb_cups.cupsGetDests = (int (*)(cups_dest_t **))
- dlsym(smb_cups.cups_hdl, "cupsGetDests");
- smb_cups.cupsFreeDests = (void (*)(int, cups_dest_t *))
- dlsym(smb_cups.cups_hdl, "cupsFreeDests");
-
- smb_cups.httpClose = (void (*)(http_t *))
- dlsym(smb_cups.cups_hdl, "httpClose");
- smb_cups.httpConnect = (http_t *(*)(const char *, int))
- dlsym(smb_cups.cups_hdl, "httpConnect");
-
- smb_cups.ippNew = (ipp_t *(*)())dlsym(smb_cups.cups_hdl, "ippNew");
- smb_cups.ippDelete = (void (*)())dlsym(smb_cups.cups_hdl, "ippDelete");
- smb_cups.ippErrorString = (char *(*)())
- dlsym(smb_cups.cups_hdl, "ippErrorString");
- smb_cups.ippAddString = (ipp_attribute_t *(*)())
- dlsym(smb_cups.cups_hdl, "ippAddString");
-
- if (smb_cups.cupsLangDefault == NULL ||
- smb_cups.cupsLangEncoding == NULL ||
- smb_cups.cupsDoFileRequest == NULL ||
- smb_cups.cupsLastError == NULL ||
- smb_cups.cupsLangFree == NULL ||
- smb_cups.cupsGetDests == NULL ||
- smb_cups.cupsFreeDests == NULL ||
- smb_cups.ippNew == NULL ||
- smb_cups.httpClose == NULL ||
- smb_cups.httpConnect == NULL ||
- smb_cups.ippDelete == NULL ||
- smb_cups.ippErrorString == NULL ||
- smb_cups.ippAddString == NULL) {
- smb_dlclose(smb_cups.cups_hdl);
- smb_cups.cups_hdl = NULL;
- (void) mutex_unlock(&spoolss_cups_mutex);
- syslog(LOG_DEBUG, "spoolss_cups_init: cannot load libcups");
- return (ENOENT);
+ if (strcasecmp(name, "Architecture") == 0) {
+ param->pType = WINREG_SZ;
+
+ if (uname(&sysname) < 0)
+ (void) strlcpy(buf, "Solaris", MAXPATHLEN);
+ else
+ (void) snprintf(buf, MAXPATHLEN, "%s %s",
+ sysname.sysname, sysname.machine);
+
+ goto encode_string;
}
- (void) mutex_unlock(&spoolss_cups_mutex);
- return (0);
-}
+ status = ERROR_FILE_NOT_FOUND;
-static void
-spoolss_cups_fini(void)
-{
- (void) mutex_lock(&spoolss_cups_mutex);
+report_error:
+ bzero(param, sizeof (struct spoolss_GetPrinterData));
+ param->Buf = reserved_buf;
+ param->status = status;
+ return (NDR_DRC_OK);
+
+encode_string:
+ wcslen = smb_wcequiv_strlen(buf) + sizeof (smb_wchar_t);
+ if (param->Size < wcslen) {
+ param->Needed = wcslen;
+ goto need_more_data;
+ }
- if (smb_cups.cups_hdl != NULL) {
- smb_dlclose(smb_cups.cups_hdl);
- smb_cups.cups_hdl = NULL;
+ if ((wcs = NDR_MALLOC(mxa, wcslen)) == NULL) {
+ status = ERROR_NOT_ENOUGH_MEMORY;
+ goto report_error;
}
- (void) mutex_unlock(&spoolss_cups_mutex);
+ (void) ndr_mbstowcs(NULL, wcs, buf, wcslen);
+ param->Buf = (uint8_t *)wcs;
+ param->Needed = wcslen;
+ param->status = ERROR_SUCCESS;
+ return (NDR_DRC_OK);
+
+need_more_data:
+ param->Size = 0;
+ param->Buf = reserved_buf;
+ param->status = ERROR_MORE_DATA;
+ return (NDR_DRC_OK);
}
void
@@ -864,73 +851,68 @@ smb_rpc_off(char *dst, char *src, uint32_t *offset, uint32_t *outoffset)
int
spoolss_s_GetPrinter(void *arg, ndr_xa_t *mxa)
{
- struct spoolss_GetPrinter *param = arg;
- struct spoolss_GetPrinter0 *pinfo0;
- struct spoolss_GetPrinter1 *pinfo1;
- struct spoolss_GetPrinter2 *pinfo2;
- struct spoolss_DeviceMode *devmode2;
- DWORD status = ERROR_SUCCESS;
- char *wname;
- uint32_t offset;
- smb_inaddr_t ipaddr;
- struct hostent *h;
- char hname[MAXHOSTNAMELEN];
- char soutbuf[MAXNAMELEN];
- char poutbuf[MAXNAMELEN];
- char ipstr[INET6_ADDRSTRLEN];
- int error;
- uint8_t *tmpbuf;
-
- if (param->BufCount == 0) {
- status = ERROR_INSUFFICIENT_BUFFER;
+ struct spoolss_GetPrinter *param = arg;
+ struct spoolss_GetPrinter0 *pinfo0;
+ struct spoolss_GetPrinter1 *pinfo1;
+ struct spoolss_GetPrinter2 *pinfo2;
+ struct spoolss_DeviceMode *devmode2;
+ ndr_hdid_t *id = (ndr_hdid_t *)&param->handle;
+ spoolss_sd_t secdesc;
+ char server[MAXNAMELEN];
+ char printer[MAXNAMELEN];
+ DWORD status = ERROR_SUCCESS;
+ char *wname;
+ uint32_t offset;
+ uint8_t *tmpbuf;
+
+ if (ndr_hdlookup(mxa, id) == NULL) {
+ status = ERROR_INVALID_HANDLE;
goto error_out;
}
- param->Buf = NDR_NEWN(mxa, char, param->BufCount);
- bzero(param->Buf, param->BufCount);
+
+ if (spoolss_getservername(server, MAXNAMELEN) != 0) {
+ status = ERROR_INTERNAL_ERROR;
+ goto error_out;
+ }
+
+ (void) snprintf(printer, MAXNAMELEN, "%s\\%s", server, SPOOLSS_PRINTER);
+
switch (param->switch_value) {
case 0:
- /*LINTED E_BAD_PTR_CAST_ALIGN*/
- pinfo0 = (struct spoolss_GetPrinter0 *)param->Buf;
- break;
case 1:
- /*LINTED E_BAD_PTR_CAST_ALIGN*/
- pinfo1 = (struct spoolss_GetPrinter1 *)param->Buf;
+ param->needed = 460;
break;
case 2:
- /*LINTED E_BAD_PTR_CAST_ALIGN*/
- pinfo2 = (struct spoolss_GetPrinter2 *)param->Buf;
+ param->needed = 712;
break;
- }
- wname = (char *)param->Buf;
-
- status = ERROR_INVALID_PARAMETER;
- if (smb_gethostname(hname, MAXHOSTNAMELEN, 0) != 0) {
- syslog(LOG_NOTICE, "spoolss_s_GetPrinter: gethostname failed");
+ default:
+ status = ERROR_INVALID_LEVEL;
goto error_out;
}
- if ((h = smb_gethostbyname(hname, &error)) == NULL) {
- syslog(LOG_NOTICE,
- "spoolss_s_GetPrinter: gethostbyname failed");
- goto error_out;
+
+ if (param->BufCount < param->needed) {
+ param->BufCount = 0;
+ param->Buf = NULL;
+ param->status = ERROR_INSUFFICIENT_BUFFER;
+ return (NDR_DRC_OK);
}
- bcopy(h->h_addr, &ipaddr, h->h_length);
- ipaddr.a_family = h->h_addrtype;
- freehostent(h);
- if (smb_inet_ntop(&ipaddr, ipstr, SMB_IPSTRLEN(ipaddr.a_family))
- == NULL) {
- syslog(LOG_NOTICE, "spoolss_s_GetPrinter: inet_ntop failed");
+
+ if ((param->Buf = NDR_MALLOC(mxa, param->BufCount)) == NULL) {
+ status = ERROR_NOT_ENOUGH_MEMORY;
goto error_out;
}
- status = ERROR_SUCCESS;
- (void) snprintf(poutbuf, MAXNAMELEN, "\\\\%s\\%s",
- ipstr, SPOOLSS_PRINTER);
- (void) snprintf(soutbuf, MAXNAMELEN, "\\\\%s", ipstr);
- param->needed = 0;
+
+ bzero(param->Buf, param->BufCount);
+ wname = (char *)param->Buf;
+ offset = param->needed;
+
switch (param->switch_value) {
case 0:
- offset = 460;
- smb_rpc_off(wname, "", &offset, &pinfo0->servername);
- smb_rpc_off(wname, poutbuf, &offset, &pinfo0->printername);
+ /*LINTED E_BAD_PTR_CAST_ALIGN*/
+ pinfo0 = (struct spoolss_GetPrinter0 *)param->Buf;
+
+ smb_rpc_off(wname, server, &offset, &pinfo0->servername);
+ smb_rpc_off(wname, printer, &offset, &pinfo0->printername);
pinfo0->cjobs = 0;
pinfo0->total_jobs = 6;
pinfo0->total_bytes = 1040771;
@@ -948,16 +930,20 @@ spoolss_s_GetPrinter(void *arg, ndr_xa_t *mxa)
pinfo0->c_setprinter = 0;
break;
case 1:
+ /*LINTED E_BAD_PTR_CAST_ALIGN*/
+ pinfo1 = (struct spoolss_GetPrinter1 *)param->Buf;
+
pinfo1->flags = PRINTER_ENUM_ICON8;
- offset = 460;
- smb_rpc_off(wname, poutbuf, &offset, &pinfo1->flags);
- smb_rpc_off(wname, poutbuf, &offset, &pinfo1->description);
- smb_rpc_off(wname, poutbuf, &offset, &pinfo1->comment);
+ smb_rpc_off(wname, printer, &offset, &pinfo1->flags);
+ smb_rpc_off(wname, printer, &offset, &pinfo1->description);
+ smb_rpc_off(wname, printer, &offset, &pinfo1->comment);
break;
case 2:
- offset = param->BufCount;
- smb_rpc_off(wname, soutbuf, &offset, &pinfo2->servername);
- smb_rpc_off(wname, poutbuf, &offset, &pinfo2->printername);
+ /*LINTED E_BAD_PTR_CAST_ALIGN*/
+ pinfo2 = (struct spoolss_GetPrinter2 *)param->Buf;
+
+ smb_rpc_off(wname, server, &offset, &pinfo2->servername);
+ smb_rpc_off(wname, printer, &offset, &pinfo2->printername);
smb_rpc_off(wname, SPOOLSS_PRINTER, &offset,
&pinfo2->sharename);
smb_rpc_off(wname, "CIFS Printer Port", &offset,
@@ -966,11 +952,26 @@ spoolss_s_GetPrinter(void *arg, ndr_xa_t *mxa)
smb_rpc_off(wname, SPOOLSS_PRINTER, &offset,
&pinfo2->comment);
smb_rpc_off(wname, "farside", &offset, &pinfo2->location);
+
+ offset -= sizeof (struct spoolss_DeviceMode);
+ pinfo2->devmode = offset;
+ /*LINTED E_BAD_PTR_CAST_ALIGN*/
+ devmode2 = (struct spoolss_DeviceMode *)(param->Buf + offset);
+
smb_rpc_off(wname, "farside", &offset, &pinfo2->sepfile);
smb_rpc_off(wname, "winprint", &offset,
&pinfo2->printprocessor);
smb_rpc_off(wname, "RAW", &offset, &pinfo2->datatype);
- smb_rpc_off(wname, "", &offset, &pinfo2->datatype);
+ smb_rpc_off(wname, "", &offset, &pinfo2->parameters);
+
+ status = spoolss_make_sd(mxa, &secdesc);
+ if (status == ERROR_SUCCESS) {
+ offset -= secdesc.sd_size;
+ pinfo2->secdesc = offset;
+ tmpbuf = (uint8_t *)(param->Buf + offset);
+ bcopy(secdesc.sd_buf, tmpbuf, secdesc.sd_size);
+ }
+
pinfo2->attributes = 0x00001048;
pinfo2->status = 0x00000000;
pinfo2->starttime = 0;
@@ -978,13 +979,10 @@ spoolss_s_GetPrinter(void *arg, ndr_xa_t *mxa)
pinfo2->cjobs = 0;
pinfo2->averageppm = 0;
pinfo2->defaultpriority = 0;
- pinfo2->devmode = 568; // offset
- /*LINTED E_BAD_PTR_CAST_ALIGN*/
- devmode2 = (struct spoolss_DeviceMode *)(param->Buf
- + pinfo2->devmode);
+
/*LINTED E_BAD_PTR_CAST_ALIGN*/
- (void) smb_mbstowcs(((smb_wchar_t *)
- (devmode2->devicename)), (const char *)poutbuf, 25);
+ (void) smb_mbstowcs((smb_wchar_t *)devmode2->devicename,
+ printer, 32);
devmode2->specversion = 0x0401;
devmode2->driverversion = 1024;
devmode2->size = 220;
@@ -1004,8 +1002,8 @@ spoolss_s_GetPrinter(void *arg, ndr_xa_t *mxa)
devmode2->ttoption = 1;
devmode2->collate = 0;
/*LINTED E_BAD_PTR_CAST_ALIGN*/
- (void) smb_mbstowcs(((smb_wchar_t *)
- (devmode2->formname)), (const char *)"Letter", 6);
+ (void) smb_mbstowcs((smb_wchar_t *)devmode2->formname,
+ "Letter", 32);
devmode2->logpixels = 0;
devmode2->bitsperpel = 0;
devmode2->pelswidth = 0;
@@ -1020,51 +1018,92 @@ spoolss_s_GetPrinter(void *arg, ndr_xa_t *mxa)
devmode2->reserved2 = 0;
devmode2->panningwidth = 0;
devmode2->panningheight = 0;
-
- pinfo2->secdesc = 84;
- tmpbuf = (uint8_t *)(pinfo2->secdesc + (uint8_t *)param->Buf);
- error = spoolss_s_make_sd(tmpbuf);
- param->needed = 712;
break;
default:
- syslog(LOG_NOTICE, "spoolss_s_GetPrinter: INVALID_LEVEL");
- status = ERROR_INVALID_LEVEL;
break;
-
}
+
+ param->status = status;
+ return (NDR_DRC_OK);
+
error_out:
+ smb_tracef("spoolss_s_GetPrinter: error %u", status);
+ bzero(param, sizeof (struct spoolss_GetPrinter));
param->status = status;
return (NDR_DRC_OK);
}
-int
-spoolss_s_make_sd(uint8_t *sd_buf)
+static int
+spoolss_getservername(char *name, size_t namelen)
{
- smb_sd_t sd;
- uint32_t status;
+ char hostname[MAXHOSTNAMELEN];
+ char ipstr[INET6_ADDRSTRLEN];
+ smb_inaddr_t ipaddr;
+ struct hostent *h;
+ const char *p;
+ int error;
+
+ if (smb_gethostname(hostname, MAXHOSTNAMELEN, 0) != 0) {
+ smb_tracef("spoolss_s_GetPrinter: gethostname failed");
+ return (-1);
+ }
- bzero(&sd, sizeof (smb_sd_t));
+ if ((h = smb_gethostbyname(hostname, &error)) == NULL) {
+ smb_tracef("spoolss_s_GetPrinter: gethostbyname failed: %d",
+ error);
+ return (-1);
+ }
- if ((status = spoolss_sd_format(&sd)) == ERROR_SUCCESS) {
- status = srvsvc_sd_set_relative(&sd, sd_buf);
- smb_sd_term(&sd);
- return (NDR_DRC_OK);
+ bcopy(h->h_addr, &ipaddr, h->h_length);
+ ipaddr.a_family = h->h_addrtype;
+ freehostent(h);
+
+ p = smb_inet_ntop(&ipaddr, ipstr, SMB_IPSTRLEN(ipaddr.a_family));
+ if (p == NULL) {
+ smb_tracef("spoolss_s_GetPrinter: inet_ntop failed");
+ return (-1);
}
- syslog(LOG_NOTICE, "spoolss_s_make_sd: error status=%d", status);
+
+ (void) snprintf(name, namelen, "\\\\%s", ipstr);
+ return (0);
+}
+
+static uint32_t
+spoolss_make_sd(ndr_xa_t *mxa, spoolss_sd_t *secdesc)
+{
+ smb_sd_t sd;
+ uint8_t *sd_buf;
+ uint32_t sd_len;
+ uint32_t status;
+
+ bzero(&sd, sizeof (smb_sd_t));
+
+ if ((status = spoolss_format_sd(&sd)) != ERROR_SUCCESS)
+ return (status);
+
+ sd_len = smb_sd_len(&sd, SMB_ALL_SECINFO);
+
+ if ((sd_buf = NDR_MALLOC(mxa, sd_len)) == NULL)
+ return (ERROR_NOT_ENOUGH_MEMORY);
+
+ secdesc->sd_buf = sd_buf;
+ secdesc->sd_size = sd_len;
+
+ status = srvsvc_sd_set_relative(&sd, sd_buf);
smb_sd_term(&sd);
- return (NDR_DRC_OK);
+ return (status);
}
static uint32_t
-spoolss_sd_format(smb_sd_t *sd)
+spoolss_format_sd(smb_sd_t *sd)
{
smb_fssd_t fs_sd;
acl_t *acl;
uint32_t status = ERROR_SUCCESS;
if (acl_fromtext("everyone@:full_set::allow", &acl) != 0) {
- syslog(LOG_ERR, "spoolss_sd_format: NOT_ENOUGH_MEMORY");
+ smb_tracef("spoolss_format_sd: NOT_ENOUGH_MEMORY");
return (ERROR_NOT_ENOUGH_MEMORY);
}
smb_fssd_init(&fs_sd, SMB_ALL_SECINFO, SMB_FSSD_FLAGS_DIR);
@@ -1073,8 +1112,9 @@ spoolss_sd_format(smb_sd_t *sd)
fs_sd.sd_zdacl = acl;
fs_sd.sd_zsacl = NULL;
- if (smb_sd_fromfs(&fs_sd, sd) != NT_STATUS_SUCCESS) {
- syslog(LOG_NOTICE, "spoolss_sd_format: ACCESS_DENIED");
+ status = smb_sd_fromfs(&fs_sd, sd);
+ if (status != NT_STATUS_SUCCESS) {
+ smb_tracef("spoolss_format_sd: %u", status);
status = ERROR_ACCESS_DENIED;
}
smb_fssd_term(&fs_sd);
@@ -1088,7 +1128,6 @@ spoolss_s_stub(void *arg, ndr_xa_t *mxa)
return (NDR_DRC_FAULT_PARAM_0_UNIMPLEMENTED);
}
-/*ARGSUSED*/
void
fixup_spoolss_RFNPCNEX(struct spoolss_RFNPCNEX *val)
{
diff --git a/usr/src/lib/smbsrv/libsmb/common/libsmb.h b/usr/src/lib/smbsrv/libsmb/common/libsmb.h
index 750c96c1f8..c5542e0cd0 100644
--- a/usr/src/lib/smbsrv/libsmb/common/libsmb.h
+++ b/usr/src/lib/smbsrv/libsmb/common/libsmb.h
@@ -227,23 +227,6 @@ extern void smb_config_getdomaininfo(char *, char *, char *, char *, char *);
extern void smb_config_setdomaininfo(char *, char *, char *, char *, char *);
extern uint32_t smb_get_dcinfo(char *, uint32_t, smb_inaddr_t *);
-CONTEXT_HANDLE(rpc_handle) rpc_handle_t;
-
-typedef struct smb_spooldoc {
- uint32_t sd_magic;
- list_node_t sd_lnd;
- smb_inaddr_t sd_ipaddr;
- int sd_spool_num;
- char sd_username[MAXNAMELEN];
- char sd_path[MAXPATHLEN];
- char sd_doc_name[MAXNAMELEN];
- char sd_printer_name[MAXPATHLEN];
- int32_t sd_fd;
- rpc_handle_t sd_handle;
-} smb_spooldoc_t;
-
-int smb_kmod_get_spool_doc(uint32_t *, char *, char *, smb_inaddr_t *);
-
/*
* buffer context structure. This is used to keep track of the buffer
* context.
@@ -895,6 +878,7 @@ uint32_t smb_sd_fromfs(smb_fssd_t *, smb_sd_t *);
/* Kernel Module Interface */
int smb_kmod_bind(void);
+boolean_t smb_kmod_isbound(void);
int smb_kmod_setcfg(smb_kmod_cfg_t *);
int smb_kmod_setgmtoff(int32_t);
int smb_kmod_start(int, int, int);
@@ -914,6 +898,7 @@ smb_netsvc_t *smb_kmod_enum_init(smb_svcenum_t *);
void smb_kmod_enum_fini(smb_netsvc_t *);
int smb_kmod_session_close(const char *, const char *);
int smb_kmod_file_close(uint32_t);
+int smb_kmod_get_spool_doc(uint32_t *, char *, char *, smb_inaddr_t *);
void smb_name_parse(char *, char **, char **);
uint32_t smb_name_validate_share(const char *);
diff --git a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
index b99ffc7033..4c847f23bb 100644
--- a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers
@@ -221,6 +221,7 @@ SYMBOL_VERSION SUNWprivate {
smb_kmod_file_close;
smb_kmod_get_open_num;
smb_kmod_get_spool_doc;
+ smb_kmod_isbound;
smb_kmod_nbtlisten;
smb_kmod_nbtreceive;
smb_kmod_session_close;
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c b/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c
index 1fcd40d1fd..e3b851695a 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_cfg.c
@@ -877,16 +877,18 @@ smb_config_get_version(smb_version_t *version)
char *p;
int rc, i;
static smb_version_t ver_table [] = {
- { SMB_MAJOR_NT, SMB_MINOR_NT },
- { SMB_MAJOR_2000, SMB_MINOR_2000 },
- { SMB_MAJOR_XP, SMB_MINOR_XP },
- { SMB_MAJOR_2003, SMB_MINOR_2003 },
- { SMB_MAJOR_VISTA, SMB_MINOR_VISTA },
- { SMB_MAJOR_2008, SMB_MINOR_2008 },
- { SMB_MAJOR_2008R2, SMB_MINOR_2008R2}
+ { 0, SMB_MAJOR_NT, SMB_MINOR_NT, 1381, 0 },
+ { 0, SMB_MAJOR_2000, SMB_MINOR_2000, 2195, 0 },
+ { 0, SMB_MAJOR_XP, SMB_MINOR_XP, 2196, 0 },
+ { 0, SMB_MAJOR_2003, SMB_MINOR_2003, 2196, 0 },
+ { 0, SMB_MAJOR_VISTA, SMB_MINOR_VISTA, 6000, 0 },
+ { 0, SMB_MAJOR_2008, SMB_MINOR_2008, 6000, 0 },
+ { 0, SMB_MAJOR_2008R2, SMB_MINOR_2008R2, 7007, 0 },
+ { 0, SMB_MAJOR_7, SMB_MINOR_7, 7007, 0 }
};
*version = ver_table[1];
+ version->sv_size = sizeof (smb_version_t);
rc = smb_config_getstr(SMB_CI_VERSION, verstr, sizeof (verstr));
if (rc != SMBD_SMF_OK)
@@ -903,6 +905,7 @@ smb_config_get_version(smb_version_t *version)
if ((tmpver.sv_major == ver_table[i].sv_major) &&
(tmpver.sv_minor == ver_table[i].sv_minor)) {
*version = ver_table[i];
+ version->sv_size = sizeof (smb_version_t);
break;
}
}
diff --git a/usr/src/lib/smbsrv/libsmb/common/smb_kmod.c b/usr/src/lib/smbsrv/libsmb/common/smb_kmod.c
index bcdc7e868a..ac5a60f7b0 100644
--- a/usr/src/lib/smbsrv/libsmb/common/smb_kmod.c
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_kmod.c
@@ -63,6 +63,12 @@ smb_kmod_bind(void)
return (0);
}
+boolean_t
+smb_kmod_isbound(void)
+{
+ return ((smbdrv_fd == -1) ? B_FALSE : B_TRUE);
+}
+
int
smb_kmod_setcfg(smb_kmod_cfg_t *cfg)
{
diff --git a/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h b/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h
index 354f394435..ba54279da4 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h
+++ b/usr/src/lib/smbsrv/libsmbns/common/libsmbns.h
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#ifndef _LIBSMBNS_H
@@ -96,7 +95,8 @@ extern boolean_t smb_ads_lookup_msdcs(char *, char *, char *, uint32_t);
extern smb_ads_host_info_t *smb_ads_find_host(char *, char *);
/* DYNDNS functions */
-extern int dyndns_start(void);
+extern void *dyndns_publisher(void *);
+extern void dyndns_start(void);
extern void dyndns_stop(void);
extern int dyndns_update(char *);
extern void dyndns_update_zones(void);
diff --git a/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers b/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers
index 05155f64fb..48af7b02ea 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers
+++ b/usr/src/lib/smbsrv/libsmbns/common/mapfile-vers
@@ -41,6 +41,7 @@ $mapfile_version 2
SYMBOL_VERSION SUNWprivate {
global:
dyndns_clear_zones;
+ dyndns_publisher;
dyndns_start;
dyndns_stop;
dyndns_update;
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c
index 52fbf9de69..0c145da369 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_browser.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
*/
#include <sys/tzfile.h>
@@ -834,8 +833,8 @@ smb_browser_send_HostAnnouncement(smb_hostinfo_t *hinfo,
++hinfo->hi_updatecnt,
next_announcement * 60000, /* Periodicity in MilliSeconds */
hinfo->hi_nbname,
- hinfo->hi_version.sv_major,
- hinfo->hi_version.sv_minor,
+ (uint8_t)hinfo->hi_version.sv_major,
+ (uint8_t)hinfo->hi_version.sv_minor,
type,
SMB_SERVER_SIGNATURE,
hinfo->hi_nic.nic_cmnt);
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c
index 24e1d175ac..26aff77bb6 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c
@@ -104,7 +104,6 @@ static dyndns_queue_t dyndns_queue;
static void dyndns_queue_request(int, const char *);
static void dyndns_queue_flush(list_t *);
-static void *dyndns_publisher(void *);
static void dyndns_process(list_t *);
static int dyndns_update_core(char *);
static int dyndns_clear_rev_zone(char *);
@@ -112,20 +111,14 @@ static void dyndns_msgid_init(void);
static int dyndns_get_msgid(void);
static void dyndns_syslog(int, int, const char *);
-int
+void
dyndns_start(void)
{
- pthread_t publisher;
- pthread_attr_t tattr;
- int rc;
-
- if (!smb_config_getbool(SMB_CI_DYNDNS_ENABLE))
- return (0);
-
(void) mutex_lock(&dyndns_queue.ddq_mtx);
+
if (dyndns_queue.ddq_state != DYNDNS_STATE_INIT) {
(void) mutex_unlock(&dyndns_queue.ddq_mtx);
- return (0);
+ return;
}
dyndns_msgid_init();
@@ -133,13 +126,8 @@ dyndns_start(void)
list_create(&dyndns_queue.ddq_list, sizeof (dyndns_qentry_t),
offsetof(dyndns_qentry_t, dqe_lnd));
dyndns_queue.ddq_state = DYNDNS_STATE_READY;
- (void) mutex_unlock(&dyndns_queue.ddq_mtx);
- (void) pthread_attr_init(&tattr);
- (void) pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
- rc = pthread_create(&publisher, &tattr, dyndns_publisher, 0);
- (void) pthread_attr_destroy(&tattr);
- return (rc);
+ (void) mutex_unlock(&dyndns_queue.ddq_mtx);
}
void
@@ -194,6 +182,9 @@ dyndns_update_zones(void)
/*
* Add a request to the queue.
+ *
+ * To comply with RFC 4120 section 6.2.1, entry->dqe_fqdn is converted
+ * to lower case.
*/
static void
dyndns_queue_request(int op, const char *fqdn)
@@ -203,33 +194,27 @@ dyndns_queue_request(int op, const char *fqdn)
if (!smb_config_getbool(SMB_CI_DYNDNS_ENABLE))
return;
+ if ((entry = malloc(sizeof (dyndns_qentry_t))) == NULL)
+ return;
+
+ bzero(entry, sizeof (dyndns_qentry_t));
+ entry->dqe_op = op;
+ (void) strlcpy(entry->dqe_fqdn, fqdn, MAXNAMELEN);
+ (void) smb_strlwr(entry->dqe_fqdn);
+
(void) mutex_lock(&dyndns_queue.ddq_mtx);
switch (dyndns_queue.ddq_state) {
case DYNDNS_STATE_READY:
case DYNDNS_STATE_PUBLISHING:
+ list_insert_tail(&dyndns_queue.ddq_list, entry);
+ (void) cond_signal(&dyndns_queue.ddq_cv);
break;
default:
- (void) mutex_unlock(&dyndns_queue.ddq_mtx);
- return;
- }
-
- if ((entry = malloc(sizeof (dyndns_qentry_t))) == NULL) {
- (void) mutex_unlock(&dyndns_queue.ddq_mtx);
- return;
+ free(entry);
+ break;
}
- bzero(entry, sizeof (dyndns_qentry_t));
- entry->dqe_op = op;
- (void) strlcpy(entry->dqe_fqdn, fqdn, MAXNAMELEN);
- /*
- * To comply with RFC 4120 section 6.2.1, entry->dqe_fqdn is converted
- * to lower case.
- */
- (void) smb_strlwr(entry->dqe_fqdn);
-
- list_insert_tail(&dyndns_queue.ddq_list, entry);
- (void) cond_signal(&dyndns_queue.ddq_cv);
(void) mutex_unlock(&dyndns_queue.ddq_mtx);
}
@@ -255,7 +240,7 @@ dyndns_queue_flush(list_t *lst)
* to retry.
*/
/*ARGSUSED*/
-static void *
+void *
dyndns_publisher(void *arg)
{
dyndns_qentry_t *entry;