Rebrand to samba-fileserver, samba-authserver for Samba4 release.
{
struct idmap_backend *entry;
- if ((version != SMB_IDMAP_INTERFACE_VERSION)) {
+ if ((version != SMB_IDMAP_INTERFACE_VERSION)) {
DEBUG(0, ("Failed to register idmap module.\n"
"The module was compiled against "
"SMB_IDMAP_INTERFACE_VERSION %d,\n"
"of samba!\n",
version, SMB_IDMAP_INTERFACE_VERSION));
return NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
+ }
if (!name || !name[0] || !methods) {
DEBUG(0,("Called with NULL pointer or empty name!\n"));
struct idmap_alloc_methods *test;
struct idmap_alloc_backend *entry;
- if ((version != SMB_IDMAP_INTERFACE_VERSION)) {
+ if ((version != SMB_IDMAP_INTERFACE_VERSION)) {
DEBUG(0, ("Failed to register idmap alloc module.\n"
"The module was compiled against "
"SMB_IDMAP_INTERFACE_VERSION %d,\n"
"of samba!\n",
version, SMB_IDMAP_INTERFACE_VERSION));
return NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
+ }
if (!name || !name[0] || !methods) {
DEBUG(0,("Called with NULL pointer or empty name!\n"));
/* setup server affinity */
get_dc_name(dom->name, realm, dc_name, &dc_ip );
-
+
status = ads_connect(ads);
if (!ADS_ERR_OK(status)) {
DEBUG(1, ("ad_idmap_init: failed to connect to AD\n"));
DEBUG(2,("ad_idmap_cached_connection: Failed to obtain schema details!\n"));
}
}
-
+
return status;
}
struct idmap_ad_context *ctx;
char *config_option;
const char *range = NULL;
- const char *schema_mode = NULL;
+ const char *schema_mode = NULL;
if ( (ctx = TALLOC_ZERO_P(dom, struct idmap_ad_context)) == NULL ) {
DEBUG(0, ("Out of memory!\n"));
}
}
- return NULL;
+ return NULL;
}
/************************************************************************
}
}
- return NULL;
+ return NULL;
}
/************************************************************************
TALLOC_CTX *memctx;
struct idmap_ad_context *ctx;
ADS_STATUS rc;
- const char *attrs[] = { "sAMAccountType",
+ const char *attrs[] = { "sAMAccountType",
"objectSid",
NULL, /* uidnumber */
NULL, /* gidnumber */
for (i = 0; ids[i]; i++) {
ids[i]->status = ID_UNKNOWN;
}
-
+
/* Only do query if we are online */
if (idmap_is_offline()) {
return NT_STATUS_FILE_IS_OFFLINE;
bidx = idx;
for (i = 0; (i < IDMAP_AD_MAX_IDS) && ids[idx]; i++, idx++) {
switch (ids[idx]->xid.type) {
- case ID_TYPE_UID:
+ case ID_TYPE_UID:
if ( ! u_filter) {
u_filter = talloc_asprintf(memctx, "(&(|"
"(sAMAccountType=%d)"
(unsigned long)ids[idx]->xid.id);
CHECK_ALLOC_DONE(u_filter);
break;
-
+
case ID_TYPE_GID:
if ( ! g_filter) {
g_filter = talloc_asprintf(memctx, "(&(|"
if (!ads_pull_uint32(ctx->ads, entry, (type==ID_TYPE_UID) ?
ctx->ad_schema->posix_uidnumber_attr :
ctx->ad_schema->posix_gidnumber_attr,
- &id))
+ &id))
{
DEBUG(1, ("Could not get unix ID\n"));
continue;
/* mark all unknown/expired ones as unmapped */
for (i = 0; ids[i]; i++) {
- if (ids[i]->status != ID_MAPPED)
+ if (ids[i]->status != ID_MAPPED)
ids[i]->status = ID_UNMAPPED;
}
TALLOC_CTX *memctx;
struct idmap_ad_context *ctx;
ADS_STATUS rc;
- const char *attrs[] = { "sAMAccountType",
+ const char *attrs[] = { "sAMAccountType",
"objectSid",
NULL, /* attr_uidnumber */
NULL, /* attr_gidnumber */
return NT_STATUS_FILE_IS_OFFLINE;
}
- ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
+ ctx = talloc_get_type(dom->private_data, struct idmap_ad_context);
- if ( (memctx = talloc_new(ctx)) == NULL ) {
+ if ( (memctx = talloc_new(ctx)) == NULL ) {
DEBUG(0, ("Out of memory!\n"));
return NT_STATUS_NO_MEMORY;
}
")(|",
ATYPE_NORMAL_ACCOUNT, ATYPE_WORKSTATION_TRUST, ATYPE_INTERDOMAIN_TRUST,
ATYPE_SECURITY_GLOBAL_GROUP, ATYPE_SECURITY_LOCAL_GROUP);
-
+
CHECK_ALLOC_DONE(filter);
bidx = idx;
sidstr = sid_binstring(talloc_tos(), ids[idx]->sid);
filter = talloc_asprintf_append_buffer(filter, "(objectSid=%s)", sidstr);
-
+
TALLOC_FREE(sidstr);
CHECK_ALLOC_DONE(filter);
}
DEBUG(10, ("No IDs found\n"));
}
- entry = res;
+ entry = res;
for (i = 0; (i < count) && entry; i++) {
DOM_SID sid;
enum id_type type;
if (!ads_pull_uint32(ctx->ads, entry, (type==ID_TYPE_UID) ?
ctx->ad_schema->posix_uidnumber_attr :
ctx->ad_schema->posix_gidnumber_attr,
- &id))
+ &id))
{
DEBUG(1, ("Could not get unix ID\n"));
continue;
/* mark all unknwoni/expired ones as unmapped */
for (i = 0; ids[i]; i++) {
- if (ids[i]->status != ID_MAPPED)
+ if (ids[i]->status != ID_MAPPED)
ids[i]->status = ID_UNMAPPED;
}
}
TALLOC_FREE( ctx->ad_schema );
-
+
return NT_STATUS_OK;
}
/************************************************************************
***********************************************************************/
-static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
- const DOM_SID *sid,
+static NTSTATUS nss_ad_get_info( struct nss_domain_entry *e,
+ const DOM_SID *sid,
TALLOC_CTX *mem_ctx,
- ADS_STRUCT *ads,
+ ADS_STRUCT *ads,
LDAPMessage *msg,
const char **homedir,
const char **shell,
/* The SFU and RFC2307 NSS plugins share everything but the init
function which sets the intended schema model to use */
-
+
static struct nss_info_methods nss_rfc2307_methods = {
.init = nss_rfc2307_init,
.get_nss_info = nss_ad_get_info,
idmap_domain interface called */
if ( !NT_STATUS_IS_OK(status_idmap_ad) ) {
- status_idmap_ad = smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION,
+ status_idmap_ad = smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION,
"ad", &ad_methods);
if ( !NT_STATUS_IS_OK(status_idmap_ad) )
- return status_idmap_ad;
+ return status_idmap_ad;
}
-
+
if ( !NT_STATUS_IS_OK( status_nss_rfc2307 ) ) {
status_nss_rfc2307 = smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
- "rfc2307", &nss_rfc2307_methods );
+ "rfc2307", &nss_rfc2307_methods );
if ( !NT_STATUS_IS_OK(status_nss_rfc2307) )
return status_nss_rfc2307;
}
if ( !NT_STATUS_IS_OK( status_nss_sfu ) ) {
status_nss_sfu = smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
- "sfu", &nss_sfu_methods );
+ "sfu", &nss_sfu_methods );
if ( !NT_STATUS_IS_OK(status_nss_sfu) )
- return status_nss_sfu;
+ return status_nss_sfu;
}
if ( !NT_STATUS_IS_OK( status_nss_sfu20 ) ) {
status_nss_sfu20 = smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
- "sfu20", &nss_sfu20_methods );
+ "sfu20", &nss_sfu20_methods );
if ( !NT_STATUS_IS_OK(status_nss_sfu20) )
- return status_nss_sfu20;
+ return status_nss_sfu20;
}
- return NT_STATUS_OK;
+ return NT_STATUS_OK;
}
-
for (i = 0; ids[i]; i++) {
ids[i]->status = ID_UNKNOWN;
}
-
+
nt_status = _idmap_adex_init(dom, NULL);
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
for (i = 0; ids[i]; i++) {
ids[i]->status = ID_UNKNOWN;
}
-
+
nt_status = _idmap_adex_init(dom, NULL);
if (!NT_STATUS_IS_OK(nt_status))
return nt_status;
for (i = 0; ids[i]; i++) {
ids[i]->status = ID_UNKNOWN;
}
-
+
nt_status = be_init(dom, NULL);
BAIL_ON_NTSTATUS_ERROR(nt_status);
for (i = 0; ids[i]; i++) {
ids[i]->status = ID_UNKNOWN;
}
-
+
nt_status = be_init(dom, NULL);
BAIL_ON_NTSTATUS_ERROR(nt_status);
case ID_TYPE_UID:
type = get_attr_key2string(idpool_attr_list,
LDAP_ATTR_UIDNUMBER);
- break;
+ break;
case ID_TYPE_GID:
type = get_attr_key2string(idpool_attr_list,
case ID_TYPE_UID:
type = get_attr_key2string(idpool_attr_list,
LDAP_ATTR_UIDNUMBER);
- break;
+ break;
case ID_TYPE_GID:
type = get_attr_key2string(idpool_attr_list,
case ID_TYPE_UID:
type = get_attr_key2string(idpool_attr_list,
LDAP_ATTR_UIDNUMBER);
- break;
+ break;
case ID_TYPE_GID:
type = get_attr_key2string(idpool_attr_list,
return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "ldap",
&idmap_ldap_methods);
}
-
-/*
+/*
Unix SMB/CIFS implementation.
idmap PASSDB backend
Copyright (C) Simo Sorce 2006
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define DBGC_CLASS DBGC_IDMAP
/*****************************
- Initialise idmap database.
+ Initialise idmap database.
*****************************/
static NTSTATUS idmap_nss_int_init(struct idmap_domain *dom,
const char *params)
-{
+{
return NT_STATUS_OK;
}
/**********************************
- lookup a set of unix ids.
+ lookup a set of unix ids.
**********************************/
static NTSTATUS idmap_nss_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
for (i = 0; ids[i]; i++) {
ids[i]->status = ID_UNKNOWN;
}
-
+
ctx = talloc_new(dom);
if ( ! ctx) {
DEBUG(0, ("Out of memory!\n"));
const char *name;
enum lsa_SidType type;
bool ret;
-
+
switch (ids[i]->xid.type) {
case ID_TYPE_UID:
pw = getpwuid((uid_t)ids[i]->xid.id);
}
/**********************************
- lookup a set of sids.
+ lookup a set of sids.
**********************************/
static NTSTATUS idmap_nss_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
for (i = 0; ids[i]; i++) {
ids[i]->status = ID_UNKNOWN;
}
-
+
ctx = talloc_new(dom);
if ( ! ctx) {
DEBUG(0, ("Out of memory!\n"));
-/*
+/*
Unix SMB/CIFS implementation.
idmap PASSDB backend
Copyright (C) Simo Sorce 2006
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define DBGC_CLASS DBGC_IDMAP
/*****************************
- Initialise idmap database.
+ Initialise idmap database.
*****************************/
static NTSTATUS idmap_pdb_init(struct idmap_domain *dom, const char *params)
-{
+{
return NT_STATUS_OK;
}
/**********************************
- lookup a set of unix ids.
+ lookup a set of unix ids.
**********************************/
static NTSTATUS idmap_pdb_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
}
/**********************************
- lookup a set of sids.
+ lookup a set of sids.
**********************************/
static NTSTATUS idmap_pdb_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
for (i = 0; ids[i]; i++) {
enum lsa_SidType type;
union unid_t id;
-
+
if (pdb_sid_to_id(ids[i]->sid, &id, &type)) {
switch (type) {
case SID_NAME_USER:
range = lp_parm_const_string(-1, config_option, "range", NULL);
if ( !range ||
(sscanf(range, "%u - %u", &ctx->low_id, &ctx->high_id) != 2) ||
- (ctx->low_id > ctx->high_id))
+ (ctx->low_id > ctx->high_id))
{
ctx->low_id = 0;
ctx->high_id = 0;
ctx->base_rid = lp_parm_int(-1, config_option, "base_rid", 0);
ctx->domain_name = talloc_strdup( ctx, dom->name );
-
+
dom->private_data = ctx;
talloc_free(config_option);
static NTSTATUS idmap_rid_id_to_sid(TALLOC_CTX *memctx, struct idmap_rid_context *ctx, struct id_map *map)
{
- struct winbindd_domain *domain;
+ struct winbindd_domain *domain;
/* apply filters before checking */
if ((map->xid.id < ctx->low_id) || (map->xid.id > ctx->high_id)) {
if ( (domain = find_domain_from_name_noinit(ctx->domain_name)) == NULL ) {
return NT_STATUS_NO_SUCH_DOMAIN;
}
-
+
sid_compose(map->sid, &domain->sid, map->xid.id - ctx->low_id + ctx->base_rid);
- /* We **really** should have some way of validating
- the SID exists and is the correct type here. But
+ /* We **really** should have some way of validating
+ the SID exists and is the correct type here. But
that is a deficiency in the idmap_rid design. */
map->status = ID_MAPPED;
}
/**********************************
- Single sid to id lookup function.
+ Single sid to id lookup function.
**********************************/
static NTSTATUS idmap_rid_sid_to_id(TALLOC_CTX *memctx, struct idmap_rid_context *ctx, struct id_map *map)
return NT_STATUS_NONE_MAPPED;
}
- /* We **really** should have some way of validating
- the SID exists and is the correct type here. But
+ /* We **really** should have some way of validating
+ the SID exists and is the correct type here. But
that is a deficiency in the idmap_rid design. */
map->status = ID_MAPPED;
}
/**********************************
- lookup a set of unix ids.
+ lookup a set of unix ids.
**********************************/
static NTSTATUS idmap_rid_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
for (i = 0; ids[i]; i++) {
ids[i]->status = ID_UNKNOWN;
}
-
+
ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
ctx = talloc_new(dom);
}
/**********************************
- lookup a set of sids.
+ lookup a set of sids.
**********************************/
static NTSTATUS idmap_rid_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
for (i = 0; ids[i]; i++) {
ids[i]->status = ID_UNKNOWN;
}
-
+
ridctx = talloc_get_type(dom->private_data, struct idmap_rid_context);
ctx = talloc_new(dom);
{
return smb_register_idmap(SMB_IDMAP_INTERFACE_VERSION, "rid", &rid_methods);
}
-
-/*
+/*
Unix SMB/CIFS implementation.
idmap TDB backend
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
Copyright (C) Jeremy Allison 2006
Copyright (C) Simo Sorce 2003-2006
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/**********************************************************************
IDMAP ALLOC TDB BACKEND
**********************************************************************/
-
+
static struct db_context *idmap_alloc_db;
/**********************************
- Initialise idmap alloc database.
+ Initialise idmap alloc database.
**********************************/
static NTSTATUS idmap_tdb_alloc_init( const char *params )
}
/**********************************
- Allocate a new id.
+ Allocate a new id.
**********************************/
static NTSTATUS idmap_tdb_allocate_id(struct unixid *xid)
/* check it is in the range */
if (hwm > high_hwm) {
- DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
+ DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
hwmtype, (unsigned long)high_hwm));
idmap_alloc_db->transaction_cancel(idmap_alloc_db);
return NT_STATUS_UNSUCCESSFUL;
/* recheck it is in the range */
if (hwm > high_hwm) {
- DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
+ DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n",
hwmtype, (unsigned long)high_hwm));
idmap_alloc_db->transaction_cancel(idmap_alloc_db);
return NT_STATUS_UNSUCCESSFUL;
}
/**********************************
- Get current highest id.
+ Get current highest id.
**********************************/
static NTSTATUS idmap_tdb_get_hwm(struct unixid *xid)
/* Warn if it is out of range */
if (hwm >= high_hwm) {
- DEBUG(0, ("Warning: %s range full!! (max: %lu)\n",
+ DEBUG(0, ("Warning: %s range full!! (max: %lu)\n",
hwmtype, (unsigned long)high_hwm));
}
}
/**********************************
- Set high id.
+ Set high id.
**********************************/
static NTSTATUS idmap_tdb_set_hwm(struct unixid *xid)
/* Warn if it is out of range */
if (hwm >= high_hwm) {
- DEBUG(0, ("Warning: %s range full!! (max: %lu)\n",
+ DEBUG(0, ("Warning: %s range full!! (max: %lu)\n",
hwmtype, (unsigned long)high_hwm));
}
}
/**********************************
- Close the alloc tdb
+ Close the alloc tdb
**********************************/
static NTSTATUS idmap_tdb_alloc_close(void)
/**********************************************************************
IDMAP MAPPING TDB BACKEND
**********************************************************************/
-
+
struct idmap_tdb_context {
struct db_context *db;
uint32_t filter_low_id;
};
/*****************************
- Initialise idmap database.
+ Initialise idmap database.
*****************************/
static NTSTATUS idmap_tdb_db_init(struct idmap_domain *dom, const char *params)
}
/**********************************
- Single id to sid lookup function.
+ Single id to sid lookup function.
**********************************/
static NTSTATUS idmap_tdb_id_to_sid(struct idmap_tdb_context *ctx, struct id_map *map)
case ID_TYPE_UID:
keystr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
break;
-
+
case ID_TYPE_GID:
keystr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
break;
ret = NT_STATUS_NONE_MAPPED;
goto done;
}
-
+
if (!string_to_sid(map->sid, (const char *)data.dptr)) {
DEBUG(10,("INVALID SID (%s) in record %s\n",
(const char *)data.dptr, keystr));
}
/**********************************
- Single sid to id lookup function.
+ Single sid to id lookup function.
**********************************/
static NTSTATUS idmap_tdb_sid_to_id(struct idmap_tdb_context *ctx, struct id_map *map)
}
/**********************************
- lookup a set of unix ids.
+ lookup a set of unix ids.
**********************************/
static NTSTATUS idmap_tdb_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
for (i = 0; ids[i]; i++) {
ids[i]->status = ID_UNKNOWN;
}
-
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
for (i = 0; ids[i]; i++) {
ids[i]->status = ID_UNMAPPED;
continue;
}
-
+
/* some fatal error occurred, return immediately */
goto done;
}
}
/**********************************
- lookup a set of sids.
+ lookup a set of sids.
**********************************/
static NTSTATUS idmap_tdb_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
for (i = 0; ids[i]; i++) {
ids[i]->status = ID_UNKNOWN;
}
-
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb_context);
for (i = 0; ids[i]; i++) {
ids[i]->status = ID_UNMAPPED;
continue;
}
-
+
/* some fatal error occurred, return immediately */
goto done;
}
data->ret = NT_STATUS_NO_MEMORY;
return -1;
}
- *data->maps = maps;
+ *data->maps = maps;
maps[num_maps].sid = talloc(maps, DOM_SID);
if ( ! maps[num_maps].sid) {
DEBUG(0, ("Out of memory!\n"));
-/*
+/*
Unix SMB/CIFS implementation.
idmap TDB2 backend, used for clustered Samba setups.
Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2003
Copyright (C) Jeremy Allison 2006
Copyright (C) Simo Sorce 2003-2006
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
static NTSTATUS idmap_tdb2_open_db(void)
{
char *db_path;
-
+
if (idmap_tdb2) {
/* its already open */
return NT_STATUS_OK;
/*
- Initialise idmap alloc database.
+ Initialise idmap alloc database.
*/
static NTSTATUS idmap_tdb2_alloc_init(const char *params)
{
/*
- Allocate a new id.
+ Allocate a new id.
*/
struct idmap_tdb2_allocate_id_context {
}
/*
- Get current highest id.
+ Get current highest id.
*/
static NTSTATUS idmap_tdb2_get_hwm(struct unixid *xid)
{
/* Warn if it is out of range */
if (hwm >= high_hwm) {
- DEBUG(0, ("Warning: %s range full!! (max: %lu)\n",
+ DEBUG(0, ("Warning: %s range full!! (max: %lu)\n",
hwmtype, (unsigned long)high_hwm));
}
}
/*
- Set high id.
+ Set high id.
*/
static NTSTATUS idmap_tdb2_set_hwm(struct unixid *xid)
{
}
/*
- Close the alloc tdb
+ Close the alloc tdb
*/
static NTSTATUS idmap_tdb2_alloc_close(void)
{
};
/*
- Initialise idmap database.
+ Initialise idmap database.
*/
static NTSTATUS idmap_tdb2_db_init(struct idmap_domain *dom,
const char *params)
unsigned long v;
cmd = talloc_asprintf(ctx, "%s ", idmap_tdb2_state.idmap_script);
- NT_STATUS_HAVE_NO_MEMORY(cmd);
+ NT_STATUS_HAVE_NO_MEMORY(cmd);
va_start(ap, fmt);
cmd = talloc_vasprintf_append(cmd, fmt, ap);
map->xid.type = ID_TYPE_UID;
} else if (sscanf(line, "GID:%lu", &v) == 1) {
map->xid.id = v;
- map->xid.type = ID_TYPE_GID;
+ map->xid.type = ID_TYPE_GID;
} else if (strncmp(line, "SID:S-", 6) == 0) {
if (!string_to_sid(map->sid, &line[4])) {
DEBUG(0,("Bad SID in '%s' from idmap script %s\n",
line, idmap_tdb2_state.idmap_script));
- return NT_STATUS_NONE_MAPPED;
+ return NT_STATUS_NONE_MAPPED;
}
} else {
DEBUG(0,("Bad reply '%s' from idmap script %s\n",
/*
- Single id to sid lookup function.
+ Single id to sid lookup function.
*/
static NTSTATUS idmap_tdb2_id_to_sid(struct idmap_tdb2_context *ctx, struct id_map *map)
{
case ID_TYPE_UID:
keystr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
break;
-
+
case ID_TYPE_GID:
keystr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
break;
&store_state);
goto done;
}
-
+
if (!string_to_sid(map->sid, (const char *)data.dptr)) {
DEBUG(10,("INVALID SID (%s) in record %s\n",
(const char *)data.dptr, keystr));
/*
- Single sid to id lookup function.
+ Single sid to id lookup function.
*/
static NTSTATUS idmap_tdb2_sid_to_id(struct idmap_tdb2_context *ctx, struct id_map *map)
{
ret = NT_STATUS_NONE_MAPPED;
goto done;
}
-
+
ret = idmap_tdb2_script(ctx, map, "SIDTOID %s", keystr);
/* store it on shared storage */
if (!NT_STATUS_IS_OK(ret)) {
DEBUG(2, ("Found INVALID record %s -> %s\n", keystr, (const char *)data.dptr));
ret = NT_STATUS_INTERNAL_DB_ERROR;
}
-
+
/* apply filters before returning result */
if ((ctx->filter_low_id && (map->xid.id < ctx->filter_low_id)) ||
(ctx->filter_high_id && (map->xid.id > ctx->filter_high_id))) {
}
/*
- lookup a set of unix ids.
+ lookup a set of unix ids.
*/
static NTSTATUS idmap_tdb2_unixids_to_sids(struct idmap_domain *dom, struct id_map **ids)
{
for (i = 0; ids[i]; i++) {
ids[i]->status = ID_UNKNOWN;
}
-
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
for (i = 0; ids[i]; i++) {
ids[i]->status = ID_UNMAPPED;
continue;
}
-
+
/* some fatal error occurred, return immediately */
goto done;
}
}
/*
- lookup a set of sids.
+ lookup a set of sids.
*/
static NTSTATUS idmap_tdb2_sids_to_unixids(struct idmap_domain *dom, struct id_map **ids)
{
for (i = 0; ids[i]; i++) {
ids[i]->status = ID_UNKNOWN;
}
-
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
for (i = 0; ids[i]; i++) {
ids[i]->status = ID_UNMAPPED;
continue;
}
-
+
/* some fatal error occurred, return immediately */
goto done;
}
/*
- set a mapping.
+ set a mapping.
*/
static NTSTATUS idmap_tdb2_set_mapping(struct idmap_domain *dom, const struct id_map *map)
ksidstr = kidstr = NULL;
/* TODO: should we filter a set_mapping using low/high filters ? */
-
+
ctx = talloc_get_type(dom->private_data, struct idmap_tdb2_context);
switch (map->xid.type) {
case ID_TYPE_UID:
kidstr = talloc_asprintf(ctx, "UID %lu", (unsigned long)map->xid.id);
break;
-
+
case ID_TYPE_GID:
kidstr = talloc_asprintf(ctx, "GID %lu", (unsigned long)map->xid.id);
break;
}
/*
- remove a mapping.
+ remove a mapping.
*/
static NTSTATUS idmap_tdb2_remove_mapping(struct idmap_domain *dom, const struct id_map *map)
{
-/*
+/*
Unix SMB/CIFS implementation.
ID Mapping
Copyright (C) Simo Sorce 2003
/*****************************************************************
Returns the SID mapped to the given UID.
If mapping is not possible returns an error.
-*****************************************************************/
+*****************************************************************/
NTSTATUS idmap_uid_to_sid(const char *domname, DOM_SID *sid, uid_t uid)
{
/*****************************************************************
Returns SID mapped to the given GID.
If mapping is not possible returns an error.
-*****************************************************************/
+*****************************************************************/
NTSTATUS idmap_gid_to_sid(const char *domname, DOM_SID *sid, gid_t gid)
{
/*****************************************************************
Returns the UID mapped to the given SID.
If mapping is not possible or SID maps to a GID returns an error.
-*****************************************************************/
+*****************************************************************/
NTSTATUS idmap_sid_to_uid(const char *dom_name, DOM_SID *sid, uid_t *uid)
{
backend:
map.sid = sid;
- map.xid.type = ID_TYPE_UID;
+ map.xid.type = ID_TYPE_UID;
ret = idmap_backends_sid_to_unixid(dom_name, &map);
/*****************************************************************
Returns the GID mapped to the given SID.
If mapping is not possible or SID maps to a UID returns an error.
-*****************************************************************/
+*****************************************************************/
NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid)
{
-/*
+/*
Unix SMB/CIFS implementation.
idMap nss template plugin
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
-
+
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
-
+
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
***********************************************************************/
static NTSTATUS nss_template_get_info( struct nss_domain_entry *e,
- const DOM_SID *sid,
+ const DOM_SID *sid,
TALLOC_CTX *ctx,
ADS_STRUCT *ads,
LDAPMessage *msg,
const char **shell,
const char **gecos,
gid_t *gid )
-{
+{
if ( !homedir || !shell || !gecos )
return NT_STATUS_INVALID_PARAMETER;
-
+
/* protect against home directories using whitespace in the
username */
*homedir = talloc_strdup( ctx, lp_template_homedir() );
if ( !*homedir || !*shell ) {
return NT_STATUS_NO_MEMORY;
}
-
+
return NT_STATUS_OK;
}
.map_from_alias = nss_template_map_from_alias,
.close_fn = nss_template_close
};
-
+
NTSTATUS nss_info_template_init( void )
{
- return smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
- "template",
- &nss_template_methods);
+ return smb_register_idmap_nss(SMB_NSS_INFO_INTERFACE_VERSION,
+ "template",
+ &nss_template_methods);
}
-
-/*
+/*
Unix SMB/CIFS implementation.
Winbind daemon for ntdom nss module
static void flush_caches(void)
{
- /* We need to invalidate cached user list entries on a SIGHUP
+ /* We need to invalidate cached user list entries on a SIGHUP
otherwise cached access denied errors due to restrict anonymous
hang around until the sequence number changes. */
/* When parent goes away we should
* remove the socket file. Not so
* when children terminate.
- */
+ */
char *path = NULL;
if (asprintf(&path, "%s/%s",
return;
}
- state->last_access = time(NULL);
+ state->last_access = time(NULL);
state->privileged = privileged;
/* glibc (?) likes to print "User defined signal 1" and exit if a
SIGUSR[12] is received before a handler is installed */
- CatchSignal(SIGUSR1, SIG_IGN);
- CatchSignal(SIGUSR2, SIG_IGN);
+ CatchSignal(SIGUSR1, SIG_IGN);
+ CatchSignal(SIGUSR2, SIG_IGN);
fault_setup((void (*)(void *))fault_quit );
dump_core_setup("winbindd");
if (!init_names())
exit(1);
- load_interfaces();
+ load_interfaces();
if (!secrets_init()) {
/* clear the cached list of trusted domains */
- wcache_tdc_clear();
+ wcache_tdc_clear();
if (!init_domain_list()) {
DEBUG(0,("unable to initialize domain list\n"));
-/*
+/*
Unix SMB/CIFS implementation.
Winbind daemon for ntdom nss module
/* get a list of users, returning a wbint_userinfo for each one */
NTSTATUS (*query_user_list)(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct wbint_userinfo **info);
/* get a list of domain groups */
NTSTATUS (*enum_dom_groups)(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct acct_info **info);
/* get a list of domain local groups */
NTSTATUS (*enum_local_groups)(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct acct_info **info);
/* convert one user or group name to a sid */
enum lsa_SidType **types);
/* lookup user info for a given SID */
- NTSTATUS (*query_user)(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
+ NTSTATUS (*query_user)(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
const DOM_SID *user_sid,
struct wbint_userinfo *user_info);
TALLOC_CTX *mem_ctx,
const DOM_SID *group_sid,
enum lsa_SidType type,
- uint32 *num_names,
- DOM_SID **sid_mem, char ***names,
+ uint32 *num_names,
+ DOM_SID **sid_mem, char ***names,
uint32 **name_types);
/* return the current global sequence number */
/* return the lockout policy */
NTSTATUS (*lockout_policy)(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
+ TALLOC_CTX *mem_ctx,
struct samr_DomInfo12 *lockout_policy);
/* return the lockout policy */
struct timed_event *event;
};
-#include "winbindd/winbindd_proto.h"
+#include "authserver/winbindd_proto.h"
#define WINBINDD_ESTABLISH_LOOP 30
#define WINBINDD_RESCAN_FREQ lp_winbind_cache_time()
/* Query display info for a realm. This is the basic user list fn */
static NTSTATUS query_user_list(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct wbint_userinfo **info)
{
ADS_STRUCT *ads = NULL;
if ( !winbindd_can_contact_domain( domain ) ) {
DEBUG(10,("query_user_list: No incoming trust for domain %s\n",
- domain->name));
+ domain->name));
return NT_STATUS_OK;
}
name = ads_pull_username(ads, mem_ctx, msg);
if ( ads_pull_sid( ads, msg, "objectSid", &user_sid ) ) {
- status = nss_get_info_cached( domain, &user_sid, mem_ctx,
+ status = nss_get_info_cached( domain, &user_sid, mem_ctx,
ads, msg, &homedir, &shell, &gecos,
&primary_gid );
}
DEBUG(3,("ads query_user_list gave %d entries\n", (*num_entries)));
done:
- if (res)
+ if (res)
ads_msgfree(ads, res);
return status;
/* list all domain groups */
static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct acct_info **info)
{
ADS_STRUCT *ads = NULL;
if ( !winbindd_can_contact_domain( domain ) ) {
DEBUG(10,("enum_dom_groups: No incoming trust for domain %s\n",
- domain->name));
+ domain->name));
return NT_STATUS_OK;
}
* According to Section 5.1(4) of RFC 2251 if a value of a type is it's
* default value, it MUST be absent. In case of extensible matching the
* "dnattr" boolean defaults to FALSE and so it must be only be present
- * when set to TRUE.
+ * when set to TRUE.
*
* When it is set to FALSE and the OpenLDAP lib (correctly) encodes a
* filter using bitwise matching rule then the buggy AD fails to decode
*
* Thanks to Ralf Haferkamp for input and testing - Guenther */
- filter = talloc_asprintf(mem_ctx, "(&(objectCategory=group)(&(groupType:dn:%s:=%d)(!(groupType:dn:%s:=%d))))",
+ filter = talloc_asprintf(mem_ctx, "(&(objectCategory=group)(&(groupType:dn:%s:=%d)(!(groupType:dn:%s:=%d))))",
ADS_LDAP_MATCHING_RULE_BIT_AND, GROUP_TYPE_SECURITY_ENABLED,
- ADS_LDAP_MATCHING_RULE_BIT_AND,
+ ADS_LDAP_MATCHING_RULE_BIT_AND,
enum_dom_local_groups ? GROUP_TYPE_BUILTIN_LOCAL_GROUP : GROUP_TYPE_RESOURCE_GROUP);
if (filter == NULL) {
DEBUG(3,("ads enum_dom_groups gave %d entries\n", (*num_entries)));
done:
- if (res)
+ if (res)
ads_msgfree(ads, res);
return status;
/* list all domain local groups */
static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct acct_info **info)
{
/*
- * This is a stub function only as we returned the domain
+ * This is a stub function only as we returned the domain
* local groups in enum_dom_groups() if the domain->native field
* was true. This is a simple performance optimization when
* using LDAP.
*
- * if we ever need to enumerate domain local groups separately,
+ * if we ever need to enumerate domain local groups separately,
* then this optimization in enum_dom_groups() will need
* to be split out
*/
* an rpc lookup sids call... R.I.P. */
/* Lookup user information from a rid */
-static NTSTATUS query_user(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
+static NTSTATUS query_user(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *sid,
struct wbint_userinfo *info)
{
ADS_STRUCT *ads = NULL;
/* try netsamlogon cache first */
- if ( (user = netsamlogon_cache_get( mem_ctx, sid )) != NULL )
+ if ( (user = netsamlogon_cache_get( mem_ctx, sid )) != NULL )
{
- DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
+ DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
sid_string_dbg(sid)));
sid_compose(&info->user_sid, &domain->sid, user->base.rid);
info->acct_name = talloc_strdup(mem_ctx, user->base.account_name.string);
info->full_name = talloc_strdup(mem_ctx, user->base.full_name.string);
- nss_get_info_cached( domain, sid, mem_ctx, NULL, NULL,
- &info->homedir, &info->shell, &info->full_name,
+ nss_get_info_cached( domain, sid, mem_ctx, NULL, NULL,
+ &info->homedir, &info->shell, &info->full_name,
&gid );
info->primary_gid = gid;
domain->name));
/* We still need to generate some basic information
- about the user even if we cannot contact the
+ about the user even if we cannot contact the
domain. Most of this stuff we can deduce. */
sid_copy( &info->user_sid, sid );
/* Try to fill in what the nss_info backend can do */
- nss_get_info_cached( domain, sid, mem_ctx, NULL, NULL,
- &info->homedir, &info->shell, &info->full_name,
+ nss_get_info_cached( domain, sid, mem_ctx, NULL, NULL,
+ &info->homedir, &info->shell, &info->full_name,
&gid);
info->primary_gid = gid;
info->acct_name = ads_pull_username(ads, mem_ctx, msg);
- nss_get_info_cached( domain, sid, mem_ctx, ads, msg,
- &info->homedir, &info->shell, &info->full_name,
+ nss_get_info_cached( domain, sid, mem_ctx, ads, msg,
+ &info->homedir, &info->shell, &info->full_name,
&gid);
info->primary_gid = gid;
DEBUG(3,("ads query_user gave %s\n", info->acct_name));
done:
- if (msg)
+ if (msg)
ads_msgfree(ads, msg);
return status;
tokenGroups are not available. */
static NTSTATUS lookup_usergroups_member(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const char *user_dn,
+ const char *user_dn,
DOM_SID *primary_group,
size_t *p_num_groups, DOM_SID **user_sids)
{
if ( !winbindd_can_contact_domain( domain ) ) {
DEBUG(10,("lookup_usergroups_members: No incoming trust for domain %s\n",
- domain->name));
+ domain->name));
return NT_STATUS_OK;
}
DEBUG(3,("ads lookup_usergroups (member) succeeded for dn=%s\n", user_dn));
done:
- if (res)
+ if (res)
ads_msgfree(ads, res);
return status;
/* Lookup groups a user is a member of. */
static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
+ const DOM_SID *sid,
uint32 *p_num_groups, DOM_SID **user_sids)
{
ADS_STRUCT *ads = NULL;
DEBUG(3,("ads: lookup_usergroups\n"));
*p_num_groups = 0;
- status = lookup_usergroups_cached(domain, mem_ctx, sid,
+ status = lookup_usergroups_cached(domain, mem_ctx, sid,
p_num_groups, user_sids);
if (NT_STATUS_IS_OK(status)) {
return NT_STATUS_OK;
if (count != 1) {
status = NT_STATUS_UNSUCCESSFUL;
DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: "
- "invalid number of results (count=%d)\n",
+ "invalid number of results (count=%d)\n",
sid_string_dbg(sid), count));
goto done;
}
if (!msg) {
- DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: NULL msg\n",
+ DEBUG(1,("lookup_usergroups(sid=%s) ads_search tokenGroups: NULL msg\n",
sid_string_dbg(sid)));
status = NT_STATUS_UNSUCCESSFUL;
goto done;
}
if (!ads_pull_uint32(ads, msg, "primaryGroupID", &primary_group_rid)) {
- DEBUG(1,("%s: No primary group for sid=%s !?\n",
+ DEBUG(1,("%s: No primary group for sid=%s !?\n",
domain->name, sid_string_dbg(sid)));
goto done;
}
count = ads_pull_sids(ads, mem_ctx, msg, "tokenGroups", &sids);
- /* there must always be at least one group in the token,
+ /* there must always be at least one group in the token,
unless we are talking to a buggy Win2k server */
/* actually this only happens when the machine account has no read
/* lookup what groups this user is a member of by DN search on
* "member" */
- status = lookup_usergroups_member(domain, mem_ctx, user_dn,
+ status = lookup_usergroups_member(domain, mem_ctx, user_dn,
&primary_group,
&num_groups, user_sids);
*p_num_groups = (uint32)num_groups;
DEBUG(10, ("lookup_groupmem: lsa_lookup_sids could "
"not map any SIDs at all.\n"));
/* Don't handle this as an error here.
- * There is nothing left to do with respect to the
+ * There is nothing left to do with respect to the
* overall result... */
}
else if (!NT_STATUS_IS_OK(status)) {
if ( !winbindd_can_contact_domain( domain ) ) {
DEBUG(10,("sequence: No incoming trust for domain %s\n",
domain->name));
- *seq = time(NULL);
+ *seq = time(NULL);
return NT_STATUS_OK;
}
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
int i;
- uint32 flags;
+ uint32 flags;
struct rpc_pipe_client *cli;
int ret_count;
NETR_TRUST_FLAG_IN_FOREST;
} else {
flags = NETR_TRUST_FLAG_IN_FOREST;
- }
+ }
result = cm_connect_netlogon(domain, &cli);
if (!NT_STATUS_IS_OK(result)) {
DEBUG(5, ("trusted_domains: Could not open a connection to %s "
- "for PIPE_NETLOGON (%s)\n",
+ "for PIPE_NETLOGON (%s)\n",
domain->name, nt_errstr(result)));
return NT_STATUS_UNSUCCESSFUL;
}
-/*
+/*
Unix SMB/CIFS implementation.
Async helpers for blocking functions
-/*
+/*
Unix SMB/CIFS implementation.
Winbind cache backend functions
init_dc_connection( domain );
}
- /*
+ /*
OK. listen up becasue I'm only going to say this once.
We have the following scenarios to consider
(a) trusted AD domains on a Samba DC,
(b) trusted AD domains and we are joined to a non-kerberos domain
(c) trusted AD domains and we are joined to a kerberos (AD) domain
- For (a) we can always contact the trusted domain using krb5
+ For (a) we can always contact the trusted domain using krb5
since we have the domain trust account password
- For (b) we can only use RPC since we have no way of
+ For (b) we can only use RPC since we have no way of
getting a krb5 ticket in our own domain
For (c) we can always use krb5 since we have a kerberos trust
#ifdef HAVE_ADS
struct winbindd_domain *our_domain = domain;
- /* find our domain first so we can figure out if we
+ /* find our domain first so we can figure out if we
are joined to a kerberized domain */
if ( !domain->primary )
static bool centry_check_bytes(struct cache_entry *centry, size_t nbytes)
{
if (centry->len - centry->ofs < nbytes) {
- DEBUG(0,("centry corruption? needed %u bytes, have %d\n",
+ DEBUG(0,("centry corruption? needed %u bytes, have %d\n",
(unsigned int)nbytes,
centry->len - centry->ofs));
return false;
}
/*
- pull a uint32 from a cache entry
+ pull a uint32 from a cache entry
*/
static uint32 centry_uint32(struct cache_entry *centry)
{
}
/*
- pull a uint16 from a cache entry
+ pull a uint16 from a cache entry
*/
static uint16 centry_uint16(struct cache_entry *centry)
{
}
/*
- pull a uint8 from a cache entry
+ pull a uint8 from a cache entry
*/
static uint8 centry_uint8(struct cache_entry *centry)
{
}
/*
- pull a NTTIME from a cache entry
+ pull a NTTIME from a cache entry
*/
static NTTIME centry_nttime(struct cache_entry *centry)
{
}
/* pull a string from a cache entry, using the supplied
- talloc context
+ talloc context
*/
static char *centry_string(struct cache_entry *centry, TALLOC_CTX *mem_ctx)
{
}
/* pull a hash16 from a cache entry, using the supplied
- talloc context
+ talloc context
*/
static char *centry_hash16(struct cache_entry *centry, TALLOC_CTX *mem_ctx)
{
len = centry_uint8(centry);
if (len != 16) {
- DEBUG(0,("centry corruption? hash len (%u) != 16\n",
+ DEBUG(0,("centry corruption? hash len (%u) != 16\n",
len ));
return NULL;
}
}
/* pull a sid from a cache entry, using the supplied
- talloc context
+ talloc context
*/
static bool centry_sid(struct cache_entry *centry, struct dom_sid *sid)
{
ret = (domain->sequence_number == DOM_SEQUENCE_NONE);
if (ret)
- DEBUG(10,("wcache_server_down: server for Domain %s down\n",
+ DEBUG(10,("wcache_server_down: server for Domain %s down\n",
domain->name ));
return ret;
}
return NT_STATUS_UNSUCCESSFUL;
}
- DEBUG(10,("fetch_cache_seqnum: success [%s][%u @ %u]\n",
- domain->name, domain->sequence_number,
+ DEBUG(10,("fetch_cache_seqnum: success [%s][%u @ %u]\n",
+ domain->name, domain->sequence_number,
(uint32)domain->last_seq_check));
return NT_STATUS_OK;
goto done;
}
- /* important! make sure that we know if this is a native
+ /* important! make sure that we know if this is a native
mode domain or not. And that we can contact it. */
- if ( winbindd_can_contact_domain( domain ) ) {
- status = domain->backend->sequence_number(domain,
+ if ( winbindd_can_contact_domain( domain ) ) {
+ status = domain->backend->sequence_number(domain,
&domain->sequence_number);
} else {
/* just use the current time */
store_cache_seqnum( domain );
done:
- DEBUG(10, ("refresh_sequence_number: %s seq number is now %d\n",
+ DEBUG(10, ("refresh_sequence_number: %s seq number is now %d\n",
domain->name, domain->sequence_number));
return;
/* if the server is OK and our cache entry came from when it was down then
the entry is invalid */
- if ((domain->sequence_number != DOM_SEQUENCE_NONE) &&
+ if ((domain->sequence_number != DOM_SEQUENCE_NONE) &&
(centry->sequence_number == DOM_SEQUENCE_NONE)) {
DEBUG(10,("centry_expired: Key %s for domain %s invalid sequence.\n",
keystr, domain->name ));
/* if the server is down or the cache entry is not older than the
current sequence number then it is OK */
- if (wcache_server_down(domain) ||
+ if (wcache_server_down(domain) ||
centry->sequence_number == domain->sequence_number) {
DEBUG(10,("centry_expired: Key %s for domain %s is good.\n",
keystr, domain->name ));
fetch an entry from the cache, with a varargs key. auto-fetch the sequence
number and return status
*/
-static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
+static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
struct winbindd_domain *domain,
const char *format, ...) PRINTF_ATTRIBUTE(3,4);
-static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
+static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
struct winbindd_domain *domain,
const char *format, ...)
{
}
/*
- make sure we have at least len bytes available in a centry
+ make sure we have at least len bytes available in a centry
*/
static void centry_expand(struct cache_entry *centry, uint32 len)
{
}
/*
- push a uint32 into a centry
+ push a uint32 into a centry
*/
static void centry_put_uint32(struct cache_entry *centry, uint32 v)
{
}
/*
- push a uint16 into a centry
+ push a uint16 into a centry
*/
static void centry_put_uint16(struct cache_entry *centry, uint16 v)
{
}
/*
- push a uint8 into a centry
+ push a uint8 into a centry
*/
static void centry_put_uint8(struct cache_entry *centry, uint8 v)
{
centry->ofs += 1;
}
-/*
- push a string into a centry
+/*
+ push a string into a centry
*/
static void centry_put_string(struct cache_entry *centry, const char *s)
{
centry->ofs += len;
}
-/*
+/*
push a 16 byte hash into a centry - treat as 16 byte string.
*/
static void centry_put_hash16(struct cache_entry *centry, const uint8 val[16])
centry->ofs += 16;
}
-static void centry_put_sid(struct cache_entry *centry, const DOM_SID *sid)
+static void centry_put_sid(struct cache_entry *centry, const DOM_SID *sid)
{
fstring sid_string;
centry_put_string(centry, sid_to_fstring(sid_string, sid));
/*
- push a NTTIME into a centry
+ push a NTTIME into a centry
*/
static void centry_put_nttime(struct cache_entry *centry, NTTIME nt)
{
free(kstr);
}
-static void wcache_save_name_to_sid(struct winbindd_domain *domain,
+static void wcache_save_name_to_sid(struct winbindd_domain *domain,
NTSTATUS status, const char *domain_name,
- const char *name, const DOM_SID *sid,
+ const char *name, const DOM_SID *sid,
enum lsa_SidType type)
{
struct cache_entry *centry;
centry_free(centry);
}
-static void wcache_save_sid_to_name(struct winbindd_domain *domain, NTSTATUS status,
+static void wcache_save_sid_to_name(struct winbindd_domain *domain, NTSTATUS status,
const DOM_SID *sid, const char *domain_name, const char *name, enum lsa_SidType type)
{
struct cache_entry *centry;
}
centry_end(centry, "SN/%s", sid_to_fstring(sid_string, sid));
- DEBUG(10,("wcache_save_sid_to_name: %s -> %s (%s)\n", sid_string,
+ DEBUG(10,("wcache_save_sid_to_name: %s -> %s (%s)\n", sid_string,
name, nt_errstr(status)));
centry_free(centry);
}
/* Lookup creds for a SID - copes with old (unsalted) creds as well
as new salted ones. */
-NTSTATUS wcache_get_creds(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
+NTSTATUS wcache_get_creds(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
const DOM_SID *sid,
const uint8 **cached_nt_pass,
const uint8 **cached_salt)
centry = wcache_fetch(cache, domain, "CRED/%s",
sid_to_fstring(tmp, sid));
if (!centry) {
- DEBUG(10,("wcache_get_creds: entry for [CRED/%s] not found\n",
+ DEBUG(10,("wcache_get_creds: entry for [CRED/%s] not found\n",
sid_string_dbg(sid)));
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
}
/* Bad (old) cred cache. Delete and pretend we
don't have it. */
- DEBUG(0,("wcache_get_creds: bad entry for [CRED/%s] - deleting\n",
+ DEBUG(0,("wcache_get_creds: bad entry for [CRED/%s] - deleting\n",
sidstr));
wcache_delete("CRED/%s", sidstr);
centry_free(centry);
/* Store creds for a SID - only writes out new salted ones. */
-NTSTATUS wcache_save_creds(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
+NTSTATUS wcache_save_creds(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *sid,
const uint8 nt_pass[NT_HASH_LEN])
{
struct cache_entry *centry;
/* Query display info. This is the basic user list fn */
static NTSTATUS query_user_list(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct wbint_userinfo **info)
{
struct winbind_cache *cache = get_cache(domain);
centry_sid(centry, &(*info)[i].group_sid);
}
-do_cached:
+do_cached:
status = centry->status;
DEBUG(10,("query_user_list: [Cached] - cached list for domain %s status: %s\n",
}
}
- } while (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) &&
+ } while (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) &&
(retry++ < 5));
/* and save it */
centry_put_sid(centry, &(*info)[i].group_sid);
if (domain->backend && domain->backend->consistent) {
/* when the backend is consistent we can pre-prime some mappings */
- wcache_save_name_to_sid(domain, NT_STATUS_OK,
+ wcache_save_name_to_sid(domain, NT_STATUS_OK,
domain->name,
- (*info)[i].acct_name,
+ (*info)[i].acct_name,
&(*info)[i].user_sid,
SID_NAME_USER);
- wcache_save_sid_to_name(domain, NT_STATUS_OK,
+ wcache_save_sid_to_name(domain, NT_STATUS_OK,
&(*info)[i].user_sid,
domain->name,
- (*info)[i].acct_name,
+ (*info)[i].acct_name,
SID_NAME_USER);
wcache_save_user(domain, NT_STATUS_OK, &(*info)[i]);
}
- }
+ }
centry_end(centry, "UL/%s", domain->name);
centry_free(centry);
/* list all domain groups */
static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct acct_info **info)
{
struct winbind_cache *cache = get_cache(domain);
(*info)[i].rid = centry_uint32(centry);
}
-do_cached:
+do_cached:
status = centry->status;
DEBUG(10,("enum_dom_groups: [Cached] - cached list for domain %s status: %s\n",
centry_put_string(centry, (*info)[i].acct_name);
centry_put_string(centry, (*info)[i].acct_desc);
centry_put_uint32(centry, (*info)[i].rid);
- }
+ }
centry_end(centry, "GL/%s/domain", domain->name);
centry_free(centry);
/* list all domain groups */
static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct acct_info **info)
{
struct winbind_cache *cache = get_cache(domain);
(*info)[i].rid = centry_uint32(centry);
}
-do_cached:
+do_cached:
/* If we are returning cached data and the domain controller
is down then we don't know whether the data is up to date
centry_put_uint32(centry, *num_groups);
for (i=0; i<(*num_groups); i++) {
centry_put_sid(centry, &(*user_gids)[i]);
- }
+ }
centry_end(centry, "UG/%s", sid_to_fstring(sid_string, user_sid));
centry_free(centry);
centry_put_sid(centry, &(*sid_mem)[i]);
centry_put_string(centry, (*names)[i]);
centry_put_uint32(centry, (*name_types)[i]);
- }
+ }
centry_end(centry, "GM/%s", sid_to_fstring(sid_string, group_sid));
centry_free(centry);
return NT_STATUS_OK;
}
-/* enumerate trusted domains
+/* enumerate trusted domains
* (we need to have the list of trustdoms in the cache when we go offline) -
* Guenther */
static NTSTATUS trusted_domains(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
struct netr_DomainTrustList *trusts)
{
- NTSTATUS status;
+ NTSTATUS status;
struct winbind_cache *cache;
struct winbindd_tdc_domain *dom_list = NULL;
size_t num_domains = 0;
do_query:
/* Return status value returned by seq number check */
- if (!NT_STATUS_IS_OK(domain->last_status))
- return domain->last_status;
+ if (!NT_STATUS_IS_OK(domain->last_status))
+ return domain->last_status;
DEBUG(10,("trusted_domains: [Cached] - doing backend query for info for domain %s\n",
domain->name ));
if (!NT_STATUS_IS_ERR(status)) {
status = NT_STATUS_OK;
}
- return status;
-}
+ return status;
+}
/* get lockout policy */
static NTSTATUS lockout_policy(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
+ TALLOC_CTX *mem_ctx,
struct samr_DomInfo12 *policy)
{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
+ struct winbind_cache *cache = get_cache(domain);
+ struct cache_entry *centry = NULL;
+ NTSTATUS status;
bool old_status;
old_status = domain->online;
centry = wcache_fetch(cache, domain, "LOC_POL/%s", domain->name);
if (!centry)
- goto do_query;
+ goto do_query;
do_fetch_cache:
policy->lockout_duration = centry_nttime(centry);
policy->lockout_window = centry_nttime(centry);
policy->lockout_threshold = centry_uint16(centry);
- status = centry->status;
+ status = centry->status;
DEBUG(10,("lockout_policy: [Cached] - cached info for domain %s status: %s\n",
domain->name, nt_errstr(status) ));
- centry_free(centry);
- return status;
+ centry_free(centry);
+ return status;
do_query:
ZERO_STRUCTP(policy);
/* Return status value returned by seq number check */
- if (!NT_STATUS_IS_OK(domain->last_status))
- return domain->last_status;
+ if (!NT_STATUS_IS_OK(domain->last_status))
+ return domain->last_status;
DEBUG(10,("lockout_policy: [Cached] - doing backend query for info for domain %s\n",
domain->name ));
}
}
/* and save it */
- refresh_sequence_number(domain, false);
+ refresh_sequence_number(domain, false);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
wcache_save_lockout_policy(domain, status, policy);
- return status;
+ return status;
}
/* get password policy */
/* Invalidate cached user and group lists coherently */
-static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
+static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
void *state)
{
if (strncmp((const char *)kbuf.dptr, "UL/", 3) == 0 ||
/* Invalidate the getpwnam and getgroups entries for a winbindd domain */
-void wcache_invalidate_samlogon(struct winbindd_domain *domain,
+void wcache_invalidate_samlogon(struct winbindd_domain *domain,
struct netr_SamInfo3 *info3)
{
DOM_SID sid;
/* when working offline we must not clear the cache on restart */
wcache->tdb = tdb_open_log(cache_path("winbindd_cache.tdb"),
- WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
- lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST),
+ WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
+ lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST),
O_RDWR|O_CREAT, 0600);
if (wcache->tdb == NULL) {
return NT_STATUS_IS_OK(status);
}
-void cache_name2sid(struct winbindd_domain *domain,
+void cache_name2sid(struct winbindd_domain *domain,
const char *domain_name, const char *name,
enum lsa_SidType type, const DOM_SID *sid)
{
* ignore these things on cleanup.
*/
-static int traverse_fn_cleanup(TDB_CONTEXT *the_tdb, TDB_DATA kbuf,
+static int traverse_fn_cleanup(TDB_CONTEXT *the_tdb, TDB_DATA kbuf,
TDB_DATA dbuf, void *state)
{
struct cache_entry *centry;
/* when working offline we must not clear the cache on restart */
wcache->tdb = tdb_open_log(cache_path("winbindd_cache.tdb"),
- WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
- lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST),
+ WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
+ lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST),
O_RDWR|O_CREAT, 0600);
if (!wcache->tdb) {
/* Count cached creds */
-static int traverse_fn_cached_creds(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
- void *state)
+static int traverse_fn_cached_creds(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
+ void *state)
{
int *cred_count = (int*)state;
-
+
if (strncmp((const char *)kbuf.dptr, "CRED/", 5) == 0) {
(*cred_count)++;
}
if (!cache->tdb) {
return NT_STATUS_INTERNAL_DB_ERROR;
}
-
+
tdb_traverse(cache->tdb, traverse_fn_cached_creds, (void *)count);
return NT_STATUS_OK;
};
static struct cred_list *wcache_cred_list;
-static int traverse_fn_get_credlist(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
+static int traverse_fn_get_credlist(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf,
void *state)
{
struct cred_list *cred;
/* save a copy of the key */
- fstrcpy(cred->name, (const char *)kbuf.dptr);
+ fstrcpy(cred->name, (const char *)kbuf.dptr);
DLIST_ADD(wcache_cred_list, cred);
}
return 0;
}
-NTSTATUS wcache_remove_oldest_cached_creds(struct winbindd_domain *domain, const DOM_SID *sid)
+NTSTATUS wcache_remove_oldest_cached_creds(struct winbindd_domain *domain, const DOM_SID *sid)
{
struct winbind_cache *cache = get_cache(domain);
NTSTATUS status;
}
/* we possibly already have an entry */
- if (sid && NT_STATUS_IS_OK(wcache_cached_creds_exist(domain, sid))) {
+ if (sid && NT_STATUS_IS_OK(wcache_cached_creds_exist(domain, sid))) {
fstring key_str, tmp;
data = tdb_fetch(cache->tdb, string_tdb_data(cred->name));
if (!data.dptr) {
- DEBUG(10,("wcache_remove_oldest_cached_creds: entry for [%s] not found\n",
+ DEBUG(10,("wcache_remove_oldest_cached_creds: entry for [%s] not found\n",
cred->name));
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
goto done;
Validate functions for all possible cache tdb keys.
***********************************************************************/
-static struct cache_entry *create_centry_validate(const char *kstr, TDB_DATA data,
+static struct cache_entry *create_centry_validate(const char *kstr, TDB_DATA data,
struct tdb_validation_status *state)
{
struct cache_entry *centry;
return 0;
}
-static int validate_trustdomcache(TALLOC_CTX *mem_ctx, const char *keystr,
+static int validate_trustdomcache(TALLOC_CTX *mem_ctx, const char *keystr,
TDB_DATA dbuf,
struct tdb_validation_status *state)
{
{
if (dbuf.dsize != 4) {
DEBUG(0, ("validate_cache_version: Corrupt cache for "
- "key %s (len %u != 4) ?\n",
+ "key %s (len %u != 4) ?\n",
keystr, (unsigned int)dbuf.dsize));
state->bad_entry = true;
state->success = false;
return 1;
}
- ret = key_val[i].validate_data_fn(mem_ctx, keystr, dbuf,
+ ret = key_val[i].validate_data_fn(mem_ctx, keystr, dbuf,
v_state);
SAFE_FREE(keystr);
smb_panic_fn = validate_panic;
- tdb = tdb_open_log(tdb_path,
+ tdb = tdb_open_log(tdb_path,
WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
- ( lp_winbind_offline_logon()
- ? TDB_DEFAULT
+ ( lp_winbind_offline_logon()
+ ? TDB_DEFAULT
: TDB_DEFAULT | TDB_CLEAR_IF_FIRST ),
- O_RDWR|O_CREAT,
+ O_RDWR|O_CREAT,
0600);
if (!tdb) {
DEBUG(0, ("winbindd_validate_cache: "
********************************************************************/
static bool add_wbdomain_to_tdc_array( struct winbindd_domain *new_dom,
- struct winbindd_tdc_domain **domains,
+ struct winbindd_tdc_domain **domains,
size_t *num_domains )
{
struct winbindd_tdc_domain *list = NULL;
list = TALLOC_ARRAY( NULL, struct winbindd_tdc_domain, 1 );
idx = 0;
} else {
- list = TALLOC_REALLOC_ARRAY( *domains, *domains,
- struct winbindd_tdc_domain,
+ list = TALLOC_REALLOC_ARRAY( *domains, *domains,
+ struct winbindd_tdc_domain,
(*num_domains)+1);
- idx = *num_domains;
+ idx = *num_domains;
}
ZERO_STRUCT( list[idx] );
}
if ( new_dom->domain_flags != 0x0 )
- list[idx].trust_flags = new_dom->domain_flags;
+ list[idx].trust_flags = new_dom->domain_flags;
if ( new_dom->domain_type != 0x0 )
list[idx].trust_type = new_dom->domain_type;
if ( !set_only ) {
*domains = list;
- *num_domains = idx + 1;
+ *num_domains = idx + 1;
}
return true;
}
key = string_term_tdb_data(keystr);
- return key;
+ return key;
}
/*********************************************************************
********************************************************************/
-static int pack_tdc_domains( struct winbindd_tdc_domain *domains,
+static int pack_tdc_domains( struct winbindd_tdc_domain *domains,
size_t num_domains,
unsigned char **buf )
{
buflen = 0;
- again:
+ again:
len = 0;
/* Store the number of array items first */
- len += tdb_pack( buffer+len, buflen-len, "d",
+ len += tdb_pack( buffer+len, buflen-len, "d",
num_domains );
/* now pack each domain trust record */
goto again;
}
- *buf = buffer;
+ *buf = buffer;
- done:
- return buflen;
+ done:
+ return buflen;
}
/*********************************************************************
********************************************************************/
-static size_t unpack_tdc_domains( unsigned char *buf, int buflen,
+static size_t unpack_tdc_domains( unsigned char *buf, int buflen,
struct winbindd_tdc_domain **domains )
{
- fstring domain_name, dns_name, sid_string;
+ fstring domain_name, dns_name, sid_string;
uint32 type, attribs, flags;
int num_domains;
int len = 0;
/* get the number of domains */
len += tdb_unpack( buf+len, buflen-len, "d", &num_domains);
if ( len == -1 ) {
- DEBUG(5,("unpack_tdc_domains: Failed to unpack domain array\n"));
+ DEBUG(5,("unpack_tdc_domains: Failed to unpack domain array\n"));
return 0;
}
list = TALLOC_ARRAY( NULL, struct winbindd_tdc_domain, num_domains );
if ( !list ) {
DEBUG(0,("unpack_tdc_domains: Failed to talloc() domain list!\n"));
- return 0;
+ return 0;
}
for ( i=0; i<num_domains; i++ ) {
if ( len == -1 ) {
DEBUG(5,("unpack_tdc_domains: Failed to unpack domain array\n"));
- TALLOC_FREE( list );
+ TALLOC_FREE( list );
return 0;
}
list[i].domain_name = talloc_strdup( list, domain_name );
list[i].dns_name = talloc_strdup( list, dns_name );
- if ( !string_to_sid( &(list[i].sid), sid_string ) ) {
+ if ( !string_to_sid( &(list[i].sid), sid_string ) ) {
DEBUG(10,("unpack_tdc_domains: no SID for domain %s\n",
domain_name));
}
static bool wcache_tdc_store_list( struct winbindd_tdc_domain *domains, size_t num_domains )
{
- TDB_DATA key = make_tdc_key( lp_workgroup() );
+ TDB_DATA key = make_tdc_key( lp_workgroup() );
TDB_DATA data = { NULL, 0 };
int ret;
SAFE_FREE( data.dptr );
SAFE_FREE( key.dptr );
- return ( ret != -1 );
+ return ( ret != -1 );
}
/*********************************************************************
TDB_DATA key = make_tdc_key( lp_workgroup() );
TDB_DATA data = { NULL, 0 };
- *domains = NULL;
- *num_domains = 0;
+ *domains = NULL;
+ *num_domains = 0;
if ( !key.dptr )
return false;
SAFE_FREE( key.dptr );
- if ( !data.dptr )
+ if ( !data.dptr )
return false;
*num_domains = unpack_tdc_domains( data.dptr, data.dsize, domains );
DEBUG(10,("wcache_tdc_add_domain: Adding domain %s (%s), SID %s, "
"flags = 0x%x, attributes = 0x%x, type = 0x%x\n",
- domain->name, domain->alt_name,
+ domain->name, domain->alt_name,
sid_string_dbg(&domain->sid),
domain->domain_flags,
domain->domain_trust_attribs,
- domain->domain_type));
+ domain->domain_type));
if ( !init_wcache() ) {
return false;
/* add the new domain */
if ( !add_wbdomain_to_tdc_array( domain, &dom_list, &num_domains ) ) {
- goto done;
- }
+ goto done;
+ }
/* pack the domain */
if ( !wcache_tdc_store_list( dom_list, num_domains ) ) {
- goto done;
+ goto done;
}
/* Success */
done:
TALLOC_FREE( dom_list );
- return ret;
+ return ret;
}
/*********************************************************************
struct winbindd_tdc_domain *dom_list = NULL;
size_t num_domains = 0;
int i;
- struct winbindd_tdc_domain *d = NULL;
+ struct winbindd_tdc_domain *d = NULL;
DEBUG(10,("wcache_tdc_fetch_domain: Searching for domain %s\n", name));
d = TALLOC_P( ctx, struct winbindd_tdc_domain );
if ( !d )
- break;
+ break;
d->domain_name = talloc_strdup( d, dom_list[i].domain_name );
d->dns_name = talloc_strdup( d, dom_list[i].dns_name );
TALLOC_FREE( dom_list );
- return d;
+ return d;
}
wcache_tdc_store_list( NULL, 0 );
- return;
+ return;
}
/*********************************************************************
********************************************************************/
-static void wcache_save_user_pwinfo(struct winbindd_domain *domain,
+static void wcache_save_user_pwinfo(struct winbindd_domain *domain,
NTSTATUS status,
const DOM_SID *user_sid,
const char *homedir,
centry_free(centry);
}
-NTSTATUS nss_get_info_cached( struct winbindd_domain *domain,
+NTSTATUS nss_get_info_cached( struct winbindd_domain *domain,
const DOM_SID *user_sid,
TALLOC_CTX *ctx,
ADS_STRUCT *ads, LDAPMessage *msg,
*homedir = centry_string( centry, ctx );
*shell = centry_string( centry, ctx );
*gecos = centry_string( centry, ctx );
- *p_gid = centry_uint32( centry );
+ *p_gid = centry_uint32( centry );
centry_free(centry);
do_query:
- nt_status = nss_get_info( domain->name, user_sid, ctx, ads, msg,
+ nt_status = nss_get_info( domain->name, user_sid, ctx, ads, msg,
homedir, shell, gecos, p_gid );
DEBUG(10, ("nss_get_info returned %s\n", nt_errstr(nt_status)));
wcache_save_user_pwinfo( domain, nt_status, user_sid,
*homedir, *shell, *gecos, *p_gid );
- }
+ }
if ( NT_STATUS_EQUAL( nt_status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND ) ) {
DEBUG(5,("nss_get_info_cached: Setting domain %s offline\n",
set_domain_offline( domain );
}
- return nt_status;
+ return nt_status;
}
entry = find_memory_creds_by_name(state->request->data.ccache_ntlm_auth.user);
if (entry == NULL || entry->nt_hash == NULL || entry->lm_hash == NULL) {
DEBUG(10,("winbindd_dual_ccache_ntlm_auth: could not find "
- "credentials for user %s\n",
+ "credentials for user %s\n",
state->request->data.ccache_ntlm_auth.user));
goto process_result;
}
-/*
+/*
Unix SMB/CIFS implementation.
Winbind daemon connection manager
(struct winbindd_domain *)private_data;
DEBUG(10,("check_domain_online_handler: called for domain "
- "%s (online = %s)\n", domain->name,
+ "%s (online = %s)\n", domain->name,
domain->online ? "True" : "False" ));
TALLOC_FREE(domain->check_online_event);
return;
}
- /* Fork a child to test if it can contact a DC.
+ /* Fork a child to test if it can contact a DC.
If it can then send ourselves a message to
cause a reconnect. */
if ( idmap->pid != 0 ) {
messaging_send_buf(winbind_messaging_context(),
- pid_to_procid(idmap->pid),
- MSG_WINBIND_OFFLINE,
- (uint8 *)domain->name,
+ pid_to_procid(idmap->pid),
+ MSG_WINBIND_OFFLINE,
+ (uint8 *)domain->name,
strlen(domain->name)+1);
- }
+ }
}
- return;
+ return;
}
/****************************************************************
if ( idmap->pid != 0 ) {
messaging_send_buf(winbind_messaging_context(),
- pid_to_procid(idmap->pid),
- MSG_WINBIND_ONLINE,
- (uint8 *)domain->name,
+ pid_to_procid(idmap->pid),
+ MSG_WINBIND_ONLINE,
+ (uint8 *)domain->name,
strlen(domain->name)+1);
- }
+ }
}
- return;
+ return;
}
/****************************************************************
/* Choose between anonymous or authenticated connections. We need to use
an authenticated connection if DCs have the RestrictAnonymous registry
entry set > 0, or the "Additional restrictions for anonymous
- connections" set in the win2k Local Security Policy.
+ connections" set in the win2k Local Security Policy.
Caller to free() result in domain, username, password
*/
if (!*password || !**password)
*password = smb_xstrdup("");
- DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
+ DEBUG(3, ("cm_get_ipc_userpass: Retrieved auth-user from secrets.tdb [%s\\%s]\n",
*domain, *username));
} else {
struct winbindd_domain *our_domain = find_our_domain();
if (!our_domain)
- return NT_STATUS_INVALID_SERVER_STATE;
+ return NT_STATUS_INVALID_SERVER_STATE;
- name = our_domain->name;
- }
+ name = our_domain->name;
+ }
if (!get_trust_pw_clear(name, machine_password,
&account_name, NULL))
struct winbindd_domain *our_domain = find_our_domain();
if (!our_domain) {
- return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
+ return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
}
if (asprintf(machine_krb5_principal, "%s$@%s",
winbindd_set_locator_kdc_envs(domain);
ads_status = cli_session_setup_spnego(*cli,
- machine_krb5_principal,
+ machine_krb5_principal,
machine_password,
lp_workgroup(),
domain->alt_name);
lp_workgroup(), machine_account));
ads_status = cli_session_setup_spnego(*cli,
- machine_account,
- machine_password,
+ machine_account,
+ machine_password,
lp_workgroup(),
NULL);
if (!ADS_ERR_OK(ads_status)) {
return NT_STATUS_NO_MEMORY;
}
- /* we have to check the server affinity cache here since
+ /* we have to check the server affinity cache here since
later we selecte a DC based on response time and not preference */
/* Check the negative connection cache
DEBUG(10,("cm_open_connection: dcname is '%s' for domain %s\n",
domain->dcname, domain->name ));
- if (*domain->dcname
+ if (*domain->dcname
&& NT_STATUS_IS_OK(check_negative_conn_cache( domain->name, domain->dcname))
&& (resolve_name(domain->dcname, &domain->dcaddr, 0x20, true)))
{
}
}
- if ((fd == -1)
+ if ((fd == -1)
&& !find_new_dc(mem_ctx, domain, domain->dcname, &domain->dcaddr, &fd))
{
/* This is the one place where we will
/* Our primary domain doesn't need to worry about trust flags.
Force it to go through the network setup */
- if ( domain->primary ) {
- return False;
+ if ( domain->primary ) {
+ return False;
}
our_domain = find_our_domain();
if ( !connection_ok(our_domain) ) {
- DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n"));
+ DEBUG(3,("set_dc_type_and_flags_trustinfo: No connection to our domain!\n"));
return False;
}
if (!NT_STATUS_IS_OK(result)) {
DEBUG(5, ("set_dc_type_and_flags_trustinfo: Could not open "
- "a connection to %s for PIPE_NETLOGON (%s)\n",
+ "a connection to %s for PIPE_NETLOGON (%s)\n",
domain->name, nt_errstr(result)));
return False;
}
if ( (mem_ctx = talloc_init("set_dc_type_and_flags_trustinfo")) == NULL ) {
DEBUG(0,("set_dc_type_and_flags_trustinfo: talloc_init() failed!\n"));
return False;
- }
+ }
result = rpccli_netr_DsrEnumerateDomainTrusts(cli, mem_ctx,
cli->desthost,
if ( domain->domain_type == NETR_TRUST_TYPE_UPLEVEL )
domain->active_directory = True;
- /* This flag is only set if the domain is *our*
+ /* This flag is only set if the domain is *our*
primary domain and the primary domain is in
native mode */
domain->native_mode = (domain->domain_flags & NETR_TRUST_FLAG_NATIVE);
DEBUG(5, ("set_dc_type_and_flags_trustinfo: domain %s is %sin "
- "native mode.\n", domain->name,
+ "native mode.\n", domain->name,
domain->native_mode ? "" : "NOT "));
DEBUG(5,("set_dc_type_and_flags_trustinfo: domain %s is %s"
- "running active directory.\n", domain->name,
+ "running active directory.\n", domain->name,
domain->active_directory ? "" : "NOT "));
domain->initialized = True;
break;
- }
+ }
}
talloc_destroy( mem_ctx );
- return domain->initialized;
+ return domain->initialized;
}
/******************************************************************************
return;
}
- result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy2(cli, mem_ctx, True,
SEC_FLAG_MAXIMUM_ALLOWED, &pol);
if (NT_STATUS_IS_OK(result)) {
- /* This particular query is exactly what Win2k clients use
+ /* This particular query is exactly what Win2k clients use
to determine that the DC is active directory */
result = rpccli_lsa_QueryInfoPolicy2(cli, mem_ctx,
&pol,
} else {
domain->active_directory = False;
- result = rpccli_lsa_open_policy(cli, mem_ctx, True,
+ result = rpccli_lsa_open_policy(cli, mem_ctx, True,
SEC_FLAG_MAXIMUM_ALLOWED,
&pol);
}
/**********************************************************************
- Set the domain_flags (trust attributes, domain operating modes, etc...
+ Set the domain_flags (trust attributes, domain operating modes, etc...
***********************************************************************/
static void set_dc_type_and_flags( struct winbindd_domain *domain )
DEBUG(10,("set_dc_type_and_flags: setting up flags for "
"primary domain\n"));
set_dc_type_and_flags_connect( domain );
- return;
+ return;
}
/* Use our DC to get the information if possible */
if ( !set_dc_type_and_flags_trustinfo( domain ) ) {
- /* Otherwise, fallback to contacting the
+ /* Otherwise, fallback to contacting the
domain directly */
set_dc_type_and_flags_connect( domain );
}
*/
if ((conn->cli->user_name[0] == '\0') ||
- (conn->cli->domain[0] == '\0') ||
+ (conn->cli->domain[0] == '\0') ||
(conn->cli->password == NULL || conn->cli->password[0] == '\0'))
{
result = get_trust_creds(domain, &machine_password,
TALLOC_FREE(conn->lsa_pipe);
if ((conn->cli->user_name[0] == '\0') ||
- (conn->cli->domain[0] == '\0') ||
+ (conn->cli->domain[0] == '\0') ||
(conn->cli->password == NULL || conn->cli->password[0] == '\0')) {
DEBUG(10, ("cm_connect_lsa: No no user available for "
"domain %s, trying schannel\n", conn->cli->domain));
if ((!IS_DC) && (!domain->primary)) {
/* Clear the schannel request bit and drop down */
- neg_flags &= ~NETLOGON_NEG_SCHANNEL;
+ neg_flags &= ~NETLOGON_NEG_SCHANNEL;
goto no_schannel;
}
#ifdef HAVE_KRB5
/* Kinit again if we have the user password and we can't renew the old
- * tgt anymore
+ * tgt anymore
* NB
* This happens when machine are put to sleep for a very long time. */
* it, ignore error here */
ads_kdestroy(entry->ccname);
- /* Don't break the ticket refresh chain: retry
- * refreshing ticket sometime later when KDC is
+ /* Don't break the ticket refresh chain: retry
+ * refreshing ticket sometime later when KDC is
* unreachable -- BoYang. More error code handling
- * here?
+ * here?
* */
if ((ret == KRB5_KDC_UNREACH)
#endif
goto done;
} else {
- /* can this happen?
+ /* can this happen?
* No cached credentials
- * destroy ticket and refresh chain
+ * destroy ticket and refresh chain
* */
ads_kdestroy(entry->ccname);
TALLOC_FREE(entry->event);
/* evil rises here, we refresh ticket failed,
* but the ticket might be expired. Therefore,
- * When we refresh ticket failed, destory the
+ * When we refresh ticket failed, destory the
* ticket */
ads_kdestroy(entry->ccname);
/* avoid breaking the renewal chain: retry in
* lp_winbind_cache_time() seconds when the KDC was not
- * available right now.
- * the return code can be KRB5_REALM_CANT_RESOLVE.
+ * available right now.
+ * the return code can be KRB5_REALM_CANT_RESOLVE.
* More error code handling here? */
- if ((ret == KRB5_KDC_UNREACH)
+ if ((ret == KRB5_KDC_UNREACH)
|| (ret == KRB5_REALM_CANT_RESOLVE)) {
#if defined(DEBUG_KRB5_TKT_RENEWAL)
new_start = time(NULL) + 30;
/* This is evil, if the ticket was already expired.
* renew ticket function returns KRB5KRB_AP_ERR_TKT_EXPIRED.
- * But there is still a chance that we can rekinit it.
+ * But there is still a chance that we can rekinit it.
*
* This happens when user login in online mode, and then network
* down or something cause winbind goes offline for a very long time,
}
done:
- /* in cases that ticket will be unrenewable soon, we don't try to renew ticket
+ /* in cases that ticket will be unrenewable soon, we don't try to renew ticket
* but try to regain ticket if it is possible */
if (entry->renew_until && expire_time
&& (entry->renew_until <= expire_time)) {
DEBUG(3,("krb5_ticket_gain_handler: "
"could not kinit: %s\n",
error_message(ret)));
- /* evil. If we cannot do it, destroy any the __maybe__
+ /* evil. If we cannot do it, destroy any the __maybe__
* __existing__ ticket */
ads_kdestroy(entry->ccname);
goto retry_later;
goto got_ticket;
retry_later:
-
+
#if defined(DEBUG_KRB5_TKT_REGAIN)
- t = timeval_set(time(NULL) + 30, 0);
+ t = timeval_set(time(NULL) + 30, 0);
#else
t = timeval_current_ofs(MAX(30, lp_winbind_cache_time()), 0);
#endif
#endif
TALLOC_FREE(entry);
- DEBUG(10,("remove_ccache: removed ccache for user %s\n", username));
+ DEBUG(10,("remove_ccache: removed ccache for user %s\n", username));
return status;
}
NTSTATUS winbindd_store_creds(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const char *user,
- const char *pass,
+ TALLOC_CTX *mem_ctx,
+ const char *user,
+ const char *pass,
struct netr_SamInfo3 *info3,
const DOM_SID *user_sid)
{
enum lsa_SidType type;
if (!lookup_cached_name(mem_ctx,
- domain->name,
+ domain->name,
user,
&cred_sid,
&type)) {
status = wcache_remove_oldest_cached_creds(domain, &cred_sid);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10,("failed to remove oldest cached cred: %s\n",
+ DEBUG(10,("failed to remove oldest cached cred: %s\n",
nt_errstr(status)));
return status;
}
{
return winbindd_store_creds(domain, mem_ctx, user, pass, NULL, NULL);
}
-
-
-/*
+/*
Unix SMB/CIFS implementation.
Winbind child daemons
}
}
-/*
+/*
* Parent winbindd process sets its own debug level first and then
* sends a message to all the winbindd children to adjust their debug
* level to that of parents.
*/
void winbind_msg_debug(struct messaging_context *msg_ctx,
- void *private_data,
+ void *private_data,
uint32_t msg_type,
struct server_id server_id,
DATA_BLOB *data)
if ( idmap->pid != 0 ) {
messaging_send_buf(msg_ctx,
- pid_to_procid(idmap->pid),
+ pid_to_procid(idmap->pid),
MSG_WINBIND_ONLINE,
(uint8 *)domain->name,
strlen(domain->name)+1);
struct winbindd_domain *domain;
char *buf = NULL;
- if ((buf = talloc_asprintf(mem_ctx, "global:%s ",
- get_global_winbindd_state_offline() ?
+ if ((buf = talloc_asprintf(mem_ctx, "global:%s ",
+ get_global_winbindd_state_offline() ?
"Offline":"Online")) == NULL) {
return NULL;
}
for (domain = domain_list(); domain; domain = domain->next) {
- if ((buf = talloc_asprintf_append_buffer(buf, "%s:%s ",
- domain->name,
+ if ((buf = talloc_asprintf_append_buffer(buf, "%s:%s ",
+ domain->name,
domain->online ?
"Online":"Offline")) == NULL) {
return NULL;
return;
}
- messaging_send_buf(msg_ctx, *sender, MSG_WINBIND_ONLINESTATUS,
+ messaging_send_buf(msg_ctx, *sender, MSG_WINBIND_ONLINESTATUS,
(uint8 *)message, strlen(message) + 1);
talloc_destroy(mem_ctx);
if ( !winbindd_can_contact_domain( child->domain ) ) {
DEBUG(10,("account_lockout_policy_handler: Removing myself since I "
- "do not have an incoming trust to domain %s\n",
+ "do not have an incoming trust to domain %s\n",
child->domain->name));
- return;
+ return;
}
methods = child->domain->methods;
if (strequal(domain->name, domainname)) {
DEBUG(5,("child_msg_offline: marking %s offline.\n", domain->name));
set_domain_offline(domain);
- /* we are in the trusted domain, set the primary domain
+ /* we are in the trusted domain, set the primary domain
* offline too */
if (domain != primary_domain) {
set_domain_offline(primary_domain);
/*
* Initialize this high as event_add_to_select_args()
- * uses a timeval_min() on this and next_event. Fix
- * from Roel van Meer <rolek@alt001.com>.
- */
+ * uses a timeval_min() on this and next_event. Fix
+ * from Roel van Meer <rolek@alt001.com>.
+ */
t.tv_sec = 999999;
t.tv_usec = 0;
*/
#include "includes.h"
-#include "winbindd/winbindd.h"
-#include "winbindd/winbindd_proto.h"
+#include "authserver/winbindd.h"
#include "librpc/gen_ndr/srv_wbint.h"
struct wb_ndr_transport_priv {
*/
#include "includes.h"
-#include "winbindd/winbindd.h"
-#include "winbindd/winbindd_proto.h"
+#include "authserver/winbindd.h"
#include "librpc/gen_ndr/srv_wbint.h"
#include "../librpc/gen_ndr/cli_netlogon.h"
-/*
+/*
Unix SMB/CIFS implementation.
Winbind daemon for ntdom nss module
Copyright (C) Jeremy Allison 2001.
Copyright (C) Gerald (Jerry) Carter 2003.
Copyright (C) Volker Lendecke 2005
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/*
+/*
Unix SMB/CIFS implementation.
Winbind daemon - miscellaneous other functions
NONE,
};
-const char *trust_type_strings[] = {"External",
- "Forest",
+const char *trust_type_strings[] = {"External",
+ "Forest",
"In Forest",
"None"};
static enum trust_type get_trust_type(struct winbindd_tdc_domain *domain)
{
- if (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN)
+ if (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN)
return EXTERNAL;
else if (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)
return FOREST;
else if (((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) == NETR_TRUST_FLAG_IN_FOREST) &&
((domain->trust_flags & NETR_TRUST_FLAG_PRIMARY) == 0x0))
return IN_FOREST;
- return NONE;
+ return NONE;
}
static const char *get_trust_type_string(struct winbindd_tdc_domain *domain)
{
return (domain->trust_flags == 0x0) ||
((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) ==
- NETR_TRUST_FLAG_IN_FOREST) ||
+ NETR_TRUST_FLAG_IN_FOREST) ||
((domain->trust_flags & NETR_TRUST_FLAG_INBOUND) ==
- NETR_TRUST_FLAG_INBOUND);
+ NETR_TRUST_FLAG_INBOUND);
}
static bool trust_is_outbound(struct winbindd_tdc_domain *domain)
{
return (domain->trust_flags == 0x0) ||
((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) ==
- NETR_TRUST_FLAG_IN_FOREST) ||
+ NETR_TRUST_FLAG_IN_FOREST) ||
((domain->trust_flags & NETR_TRUST_FLAG_OUTBOUND) ==
- NETR_TRUST_FLAG_OUTBOUND);
+ NETR_TRUST_FLAG_OUTBOUND);
}
static bool trust_is_transitive(struct winbindd_tdc_domain *domain)
{
- if ((domain->trust_attribs == NETR_TRUST_ATTRIBUTE_NON_TRANSITIVE) ||
+ if ((domain->trust_attribs == NETR_TRUST_ATTRIBUTE_NON_TRANSITIVE) ||
(domain->trust_attribs == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) ||
(domain->trust_attribs == NETR_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL))
return False;
(unsigned long)state->pid));
if( !wcache_tdc_fetch_list( &dom_list, &num_domains )) {
- request_error(state);
+ request_error(state);
goto done;
}
for ( i = 0; i < num_domains; i++ ) {
struct winbindd_domain *domain;
- bool is_online = true;
+ bool is_online = true;
d = &dom_list[i];
domain = find_domain_from_name_noinit(d->domain_name);
state->response->length += extra_data_len;
}
- request_ok(state);
+ request_ok(state);
done:
TALLOC_FREE( dom_list );
}
request_ok(state);
}
-
goto done;
memory_ccache:
- gen_cc = talloc_strdup(mem_ctx, "MEMORY:winbindd_pam_ccache");
+ gen_cc = talloc_strdup(mem_ctx, "MEMORY:winbindd_pam_ccache");
done:
- if (gen_cc == NULL) {
+ if (gen_cc == NULL) {
DEBUG(0,("out of memory\n"));
return NULL;
}
if (contact_domain->initialized &&
contact_domain->active_directory) {
- goto try_login;
+ goto try_login;
}
if (!contact_domain->initialized) {
&info,
&reject);
- /* Windows 2003 returns NT_STATUS_PASSWORD_RESTRICTION */
+ /* Windows 2003 returns NT_STATUS_PASSWORD_RESTRICTION */
if (NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_RESTRICTION) ) {
-/*
+/*
Unix SMB/CIFS implementation.
Winbind rpc backend functions
static NTSTATUS enum_groups_internal(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct acct_info **info,
enum lsa_SidType sidtype)
{
/* List all local groups (aliases) */
static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct acct_info **info)
{
return enum_groups_internal(domain,
/* list all domain groups */
static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct acct_info **info)
{
/* BUILTIN doesn't have domain groups */
/* list all domain groups */
static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct acct_info **info)
{
return enum_groups_internal(domain,
void winbindd_check_cache_size(time_t t);
struct cache_entry *centry_start(struct winbindd_domain *domain, NTSTATUS status);
NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const DOM_SID *sid);
-NTSTATUS wcache_get_creds(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
+NTSTATUS wcache_get_creds(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
const DOM_SID *sid,
const uint8 **cached_nt_pass,
const uint8 **cached_salt);
-NTSTATUS wcache_save_creds(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
+NTSTATUS wcache_save_creds(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *sid,
const uint8 nt_pass[NT_HASH_LEN]);
-void wcache_invalidate_samlogon(struct winbindd_domain *domain,
+void wcache_invalidate_samlogon(struct winbindd_domain *domain,
struct netr_SamInfo3 *info3);
bool wcache_invalidate_cache(void);
bool wcache_invalidate_cache_noinit(void);
const char *name,
DOM_SID *sid,
enum lsa_SidType *type);
-void cache_name2sid(struct winbindd_domain *domain,
+void cache_name2sid(struct winbindd_domain *domain,
const char *domain_name, const char *name,
enum lsa_SidType type, const DOM_SID *sid);
NTSTATUS wcache_name_to_sid(struct winbindd_domain *domain,
bool wcache_tdc_add_domain( struct winbindd_domain *domain );
struct winbindd_tdc_domain * wcache_tdc_fetch_domain( TALLOC_CTX *ctx, const char *name );
void wcache_tdc_clear( void );
-NTSTATUS nss_get_info_cached( struct winbindd_domain *domain,
+NTSTATUS nss_get_info_cached( struct winbindd_domain *domain,
const DOM_SID *user_sid,
TALLOC_CTX *ctx,
ADS_STRUCT *ads, LDAPMessage *msg,
const uint8 *cached_nt_pass[NT_HASH_LEN],
const uint8 *cred_salt[NT_HASH_LEN]);
NTSTATUS winbindd_store_creds(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const char *user,
- const char *pass,
+ TALLOC_CTX *mem_ctx,
+ const char *user,
+ const char *pass,
struct netr_SamInfo3 *info3,
const DOM_SID *user_sid);
NTSTATUS winbindd_update_creds_by_info3(struct winbindd_domain *domain,
-/*
+/*
Unix SMB/CIFS implementation.
Wrapper around winbindd_rpc.c to centralize retry logic.
Copyright (C) Volker Lendecke 2005
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* List all users */
static NTSTATUS query_user_list(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct wbint_userinfo **info)
{
NTSTATUS result;
/* list all domain groups */
static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct acct_info **info)
{
NTSTATUS result;
static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct acct_info **info)
{
NTSTATUS result;
}
/* Lookup user information from a rid or username. */
-static NTSTATUS query_user(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
+static NTSTATUS query_user(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
const DOM_SID *user_sid,
struct wbint_userinfo *user_info)
{
const DOM_SID *group_sid,
enum lsa_SidType type,
uint32 *num_names,
- DOM_SID **sid_mem, char ***names,
+ DOM_SID **sid_mem, char ***names,
uint32 **name_types)
{
NTSTATUS result;
}
/* find the lockout policy of a domain */
-static NTSTATUS lockout_policy(struct winbindd_domain *domain,
+static NTSTATUS lockout_policy(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
struct samr_DomInfo12 *policy)
{
}
/* find the password policy of a domain */
-static NTSTATUS password_policy(struct winbindd_domain *domain,
+static NTSTATUS password_policy(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
struct samr_DomInfo1 *policy)
{
- NTSTATUS result;
-
+ NTSTATUS result;
+
result = msrpc_methods.password_policy(domain, mem_ctx, policy);
if (reconnect_need_retry(result))
result = msrpc_methods.password_policy(domain, mem_ctx, policy);
-
+
return result;
}
-/*
+/*
Unix SMB/CIFS implementation.
Winbind rpc backend functions
application. */
static NTSTATUS query_user_list(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct wbint_userinfo **info)
{
NTSTATUS result;
/* list all domain groups */
static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct acct_info **info)
{
struct policy_handle dom_pol;
static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
+ uint32 *num_entries,
struct acct_info **info)
{
struct policy_handle dom_pol;
}
/* Lookup user information from a rid or username. */
-static NTSTATUS query_user(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *user_sid,
+static NTSTATUS query_user(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *user_sid,
struct wbint_userinfo *user_info)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
/* try netsamlogon cache first */
- if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
+ if ( (user = netsamlogon_cache_get( mem_ctx, user_sid )) != NULL )
{
- DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
+ DEBUG(5,("query_user: Cache lookup succeeded for %s\n",
sid_string_dbg(user_sid)));
sid_compose(&user_info->user_sid, &domain->sid, user->base.rid);
user_info->primary_gid = (gid_t)-1;
return NT_STATUS_OK;
-}
+}
/* Lookup groups a user is a member of. I wish Unix had a call like this! */
static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
*user_grpsids = NULL;
/* so lets see if we have a cached user_info_3 */
- result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
+ result = lookup_usergroups_cached(domain, mem_ctx, user_sid,
num_groups, user_grpsids);
if (NT_STATUS_IS_OK(result)) {
num_query_sids = MIN(num_sids - total_sids, rangesize);
- DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
- num_queries, num_query_sids));
+ DEBUG(10,("rpc: lookup_useraliases: entering query %d for %d sids\n",
+ num_queries, num_query_sids));
if (num_query_sids) {
sid_array.sids = TALLOC_ZERO_ARRAY(mem_ctx, struct lsa_SidPtr, num_query_sids);
const DOM_SID *group_sid,
enum lsa_SidType type,
uint32 *num_names,
- DOM_SID **sid_mem, char ***names,
+ DOM_SID **sid_mem, char ***names,
uint32 **name_types)
{
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
return NT_STATUS_NO_MEMORY;
#ifdef HAVE_LDAP
- if ( domain->active_directory )
+ if ( domain->active_directory )
{
int res;
res = get_ldap_sequence_number( domain, seq );
if (res == 0)
- {
+ {
result = NT_STATUS_OK;
DEBUG(10,("domain_sequence_number: LDAP for "
"domain %s is %u\n",
alternate_name = alt_name;
/* If we have an existing domain structure, calling
- add_trusted_domain() will update the SID if
- necessary. This is important because we need the
- SID for sibling domains */
+ add_trusted_domain() will update the SID if
+ necessary. This is important because we need the
+ SID for sibling domains */
if ( find_domain_from_name_noinit(p) != NULL ) {
domain = add_trusted_domain(p, alternate_name,
continue;
}
- DEBUG(10,("rescan_forest_root_trusts: Following trust path "
+ DEBUG(10,("rescan_forest_root_trusts: Following trust path "
"for domain tree root %s (%s)\n",
- d->name, d->alt_name ));
+ d->name, d->alt_name ));
d->domain_flags = dom_list[i].trust_flags;
d->domain_type = dom_list[i].trust_type;
-/*
+/*
Unix SMB/CIFS implementation.
Winbind daemon - WINS related functions
Copyright (C) Andrew Tridgell 1999
Copyright (C) Herb Lewis 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 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#if defined(WITH_AIO)
bool write_through = BITSETW(aio_ex->req->vwv+7,0);
NTSTATUS status;
- SSVAL(outbuf,smb_vwv2,nwritten);
+ SSVAL(outbuf,smb_vwv2,nwritten);
SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
if (nwritten < (ssize_t)numtowrite) {
SCVAL(outbuf,smb_rcls,ERRHRD);
ERROR_BOTH(map_nt_error_from_unix(errcode),
ERRHRD, ERRdiskfull);
srv_set_message(outbuf,0,0,true);
- DEBUG(5,("handle_aio_write: sync_file for %s returned %s\n",
+ DEBUG(5,("handle_aio_write: sync_file for %s returned %s\n",
fsp_str_dbg(fsp), nt_errstr(status)));
}
-/*
+/*
Unix SMB/CIFS implementation.
Blocking Locking functions
Copyright (C) Jeremy Allison 1998-2003
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_LOCKING
return True;
}
- /*
+ /*
to account for unclean shutdowns by clients we need a
maximum timeout that we use for checking pending locks. If
we have any pending locks at all, then check if the pending
blr->lock_type = lock_type;
blr->offset = offset;
blr->count = count;
-
+
/* Specific brl_lock() implementations can fill this in. */
blr->blr_private = NULL;
}
/****************************************************************************
- Return a lock fail error for a lockingX call. Undo all the locks we have
+ Return a lock fail error for a lockingX call. Undo all the locks we have
obtained first.
*****************************************************************************/
data = (uint8_t *)blr->req->buf
+ ((large_file_format ? 20 : 10)*num_ulocks);
- /*
+ /*
* Data now points at the beginning of the list
* of smb_lkrng structs.
*/
data = (uint8_t *)blr->req->buf
+ ((large_file_format ? 20 : 10)*num_ulocks);
- /*
+ /*
* Data now points at the beginning of the list
* of smb_lkrng structs.
*/
fsp,
lock_pid,
count,
- offset,
+ offset,
((locktype & LOCKING_ANDX_SHARED_LOCK) ?
READ_LOCK : WRITE_LOCK),
WINDOWS_LOCK,
*/
DEBUG(10,("process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \
-Waiting....\n",
+Waiting....\n",
blr->lock_num, num_locks, fsp_str_dbg(fsp), fsp->fnum));
return False;
if (ERROR_WAS_LOCK_DENIED(status)) {
/* Still can't get the lock, just keep waiting. */
return False;
- }
+ }
/*
* We have other than a "can't get lock"
* error. Send an error and return True so we get dequeued.
-/*
+/*
* Unix SMB/CIFS implementation.
* Periodic Trust account password changing.
* Copyright (C) Andrew Tridgell 1992-1997,
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
if (remote_machine == NULL || !strcmp(remote_machine, "*")) {
/* Use the PDC *only* for this */
-
+
if ( !get_pdc_ip(domain, &pdc_ss) ) {
DEBUG(0,("Can't get IP for PDC for domain %s\n", domain));
goto failed;
/* supoport old deprecated "smbpasswd -j DOMAIN -r MACHINE" behavior */
fstrcpy( dc_name, remote_machine );
}
-
+
/* if this next call fails, then give up. We can't do
password changes on BDC's --jerry */
-
- if (!NT_STATUS_IS_OK(cli_full_connection(&cli, global_myname(), dc_name,
+
+ if (!NT_STATUS_IS_OK(cli_full_connection(&cli, global_myname(), dc_name,
NULL, 0,
- "IPC$", "IPC",
+ "IPC$", "IPC",
"", "",
"", 0, Undefined, NULL))) {
DEBUG(0,("modify_trust_password: Connection to %s failed!\n", dc_name));
nt_status = NT_STATUS_UNSUCCESSFUL;
goto failed;
}
-
+
/*
* Ok - we have an anonymous connection to the IPC$ share.
* Now start the NT Domain stuff :-).
nt_status = cli_rpc_pipe_open_noauth(
cli, &ndr_table_netlogon.syntax_id, &netlogon_pipe);
if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0,("modify_trust_password: unable to open the domain client session to machine %s. Error was : %s.\n",
+ DEBUG(0,("modify_trust_password: unable to open the domain client session to machine %s. Error was : %s.\n",
dc_name, nt_errstr(nt_status)));
cli_shutdown(cli);
cli = NULL;
nt_status = trust_pw_find_change_and_store_it(
netlogon_pipe, netlogon_pipe, domain);
-
+
cli_shutdown(cli);
cli = NULL;
-
+
failed:
if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0,("%s : change_trust_account_password: Failed to change password for domain %s.\n",
+ DEBUG(0,("%s : change_trust_account_password: Failed to change password for domain %s.\n",
current_timestring(talloc_tos(), False), domain));
}
else
DEBUG(5,("change_trust_account_password: sucess!\n"));
-
+
return nt_status;
}
-/*
+/*
Unix SMB/CIFS implementation.
Samba utility functions
Copyright (C) Andrew Tridgell 1992-1998
stermios.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
stermios.c_lflag |= ICANON;
#ifdef ONLCR
- stermios.c_oflag &= ~(ONLCR);
+ stermios.c_oflag &= ~(ONLCR);
#endif
if (tcsetattr(0, TCSANOW, &stermios) < 0)
{
#else /* ALLOW_CHANGE_PASSWORD */
-bool chgpasswd(const char *name, const struct passwd *pass,
+bool chgpasswd(const char *name, const struct passwd *pass,
const char *oldpass, const char *newpass, bool as_root)
{
DEBUG(0, ("chgpasswd: Unix Password changing not compiled in (user=%s)\n", name));
return False;
}
- if (pwd == NULL) {
+ if (pwd == NULL) {
if (acct_ctrl & ACB_PWNOTREQ) {
uchar no_pw[14];
password_encrypted = password_encrypted_with_lm_hash;
encryption_key = lanman_pw;
} else if (nt_pass_set) {
- DEBUG(1, ("NT password change supplied for user %s, but we have no NT password to check it with\n",
+ DEBUG(1, ("NT password change supplied for user %s, but we have no NT password to check it with\n",
user));
return NT_STATUS_WRONG_PASSWORD;
} else if (lm_pass_set) {
if (lp_lanman_auth()) {
- DEBUG(1, ("LM password change supplied for user %s, but we have no LanMan password to check it with\n",
+ DEBUG(1, ("LM password change supplied for user %s, but we have no LanMan password to check it with\n",
user));
} else {
- DEBUG(1, ("LM password change supplied for user %s, but we have disabled LanMan authentication\n",
+ DEBUG(1, ("LM password change supplied for user %s, but we have disabled LanMan authentication\n",
user));
}
return NT_STATUS_WRONG_PASSWORD;
} else {
- DEBUG(1, ("password change requested for user %s, but no password supplied!\n",
+ DEBUG(1, ("password change requested for user %s, but no password supplied!\n",
user));
return NT_STATUS_WRONG_PASSWORD;
}
}
if (pdb_get_account_policy(PDB_POLICY_MIN_PASSWORD_LEN, &min_len) && (str_charnum(new_passwd) < min_len)) {
- DEBUG(1, ("user %s cannot change password - password too short\n",
+ DEBUG(1, ("user %s cannot change password - password too short\n",
username));
DEBUGADD(1, (" account policy min password len = %d\n", min_len));
if (samr_reject_reason) {
static void notify_deferred_opens(struct share_mode_lock *lck)
{
- int i;
+ int i;
if (!should_notify_deferred_opens()) {
return;
}
-
- for (i=0; i<lck->num_share_modes; i++) {
- struct share_mode_entry *e = &lck->share_modes[i];
-
- if (!is_deferred_open_entry(e)) {
- continue;
- }
-
- if (procid_is_me(&e->pid)) {
- /*
- * We need to notify ourself to retry the open. Do
- * this by finding the queued SMB record, moving it to
- * the head of the queue and changing the wait time to
- * zero.
- */
- schedule_deferred_open_message_smb(e->op_mid);
- } else {
+
+ for (i=0; i<lck->num_share_modes; i++) {
+ struct share_mode_entry *e = &lck->share_modes[i];
+
+ if (!is_deferred_open_entry(e)) {
+ continue;
+ }
+
+ if (procid_is_me(&e->pid)) {
+ /*
+ * We need to notify ourself to retry the open. Do
+ * this by finding the queued SMB record, moving it to
+ * the head of the queue and changing the wait time to
+ * zero.
+ */
+ schedule_deferred_open_message_smb(e->op_mid);
+ } else {
char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
share_mode_entry_to_message(msg, e);
- messaging_send_buf(smbd_messaging_context(),
+ messaging_send_buf(smbd_messaging_context(),
e->pid, MSG_SMB_OPEN_RETRY,
(uint8 *)msg,
MSG_SMB_SHARE_MODE_ENTRY_SIZE);
- }
- }
+ }
+ }
}
/****************************************************************************
fsp->fsp_name->base_name);
/* As we now have POSIX opens which can unlink
- * with other open files we may have taken
- * this code path with more than one share mode
- * entry - ensure we only delete once by resetting
- * the delete on close flag. JRA.
- */
+ * with other open files we may have taken
+ * this code path with more than one share mode
+ * entry - ensure we only delete once by resetting
+ * the delete on close flag. JRA.
+ */
fsp->delete_on_close = false;
set_delete_on_close_lck(lck, False, NULL);
if (fsp->aio_write_behind) {
/*
- * If we're finishing write behind on a close we can get a write
+ * If we're finishing write behind on a close we can get a write
* error here, we must remember this.
*/
int ret = wait_for_aio_completion(fsp);
} else {
cancel_aio_by_fsp(fsp);
}
-
+
/*
* If we're flushing on a close we can get a write
* error here, we must remember this.
}
/****************************************************************************
- Close a directory opened by an NT SMB call.
+ Close a directory opened by an NT SMB call.
****************************************************************************/
-
+
static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
enum file_close_type close_type)
{
if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
delete_dir &&
lck->delete_token) {
-
+
/* Become the user who requested the delete. */
if (!push_sec_ctx()) {
/****************************************************************************
Close a files_struct.
****************************************************************************/
-
+
NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
enum file_close_type close_type)
{
-/*
+/*
Unix SMB/CIFS implementation.
Manage connections_struct structures
Copyright (C) Andrew Tridgell 1998
Copyright (C) Alexander Bokovoy 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 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
/* The connections bitmap is expanded in increments of BITMAP_BLOCK_SZ. The
* maximum size of the bitmap is the largest positive integer, but you will hit
find_again:
i = bitmap_find(sconn->smb1.tcons.bmap, find_offset);
-
+
if (i == -1) {
/* Expand the connections bitmap. */
int oldsz = sconn->smb1.tcons.bmap->n;
string_set(&conn->connectpath,"");
string_set(&conn->origpath,"");
-
+
DLIST_ADD(sconn->smb1.tcons.Connections, conn);
return conn;
return False;
}
}
-
+
return True;
}
free_namearray(conn->hide_list);
free_namearray(conn->veto_oplock_list);
free_namearray(conn->aio_write_behind_list);
-
+
string_free(&conn->connectpath);
string_free(&conn->origpath);
conn_free_internal(conn);
}
-
+
/****************************************************************************
receive a smbcontrol message to forcibly unmount a share
the message contains just a share name and all instances of that
-/*
+/*
Unix SMB/CIFS implementation.
connection claim routines
Copyright (C) Andrew Tridgell 1998
-/*
+/*
Unix SMB/CIFS implementation.
functions to calculate the free disk space
Copyright (C) Andrew Tridgell 1998
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
/****************************************************************************
Normalise for DOS usage.
/* convert to blocks - and don't overflow */
maxdisksize = ((maxdisksize*1024)/(*bsize))*1024;
if (*dsize > maxdisksize) *dsize = maxdisksize;
- if (*dfree > maxdisksize) *dfree = maxdisksize-1;
+ if (*dfree > maxdisksize) *dfree = maxdisksize-1;
/* the -1 should stop applications getting div by 0
errors */
- }
+ }
- if(small_query) {
+ if(small_query) {
while (*dfree > WORDMAX || *dsize > WORDMAX || *bsize < 512) {
*dfree /= 2;
*dsize /= 2;
Return number of 1K blocks available on a path and total number.
****************************************************************************/
-uint64_t sys_disk_free(connection_struct *conn, const char *path, bool small_query,
+uint64_t sys_disk_free(connection_struct *conn, const char *path, bool small_query,
uint64_t *bsize,uint64_t *dfree,uint64_t *dsize)
{
uint64_t dfree_retval;
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
/*
This module implements directory related functions for Samba.
DLIST_REMOVE(sconn->smb1.searches.dirptrs, dptr);
/*
- * Free the dnum in the bitmap. Remember the dnum value is always
+ * Free the dnum in the bitmap. Remember the dnum value is always
* biased by one with respect to the bitmap.
*/
DLIST_ADD(sconn->smb1.searches.dirptrs, dptr);
DEBUG(3,("creating new dirptr %d for path %s, expect_close = %d\n",
- dptr->dnum,path,expect_close));
+ dptr->dnum,path,expect_close));
*dptr_ret = dptr;
-/*
+/*
Unix SMB/CIFS implementation.
DMAPI Support routines
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_DMAPI
unsigned session_num;
};
-/*
- Initialise DMAPI session. The session is persistant kernel state,
- so it might already exist, in which case we merely want to
+/*
+ Initialise DMAPI session. The session is persistant kernel state,
+ so it might already exist, in which case we merely want to
reconnect to it. This function should be called as root.
*/
static int dmapi_init_session(struct smbd_dmapi_context *ctx)
talloc_free(tmp_ctx);
return -1;
}
-
+
if (dm_init_service(&version) < 0) {
DEBUG(0, ("dm_init_service failed - disabling DMAPI\n"));
do {
dm_sessid_t *new_sessions;
nsessions *= 2;
- new_sessions = TALLOC_REALLOC_ARRAY(tmp_ctx, sessions,
+ new_sessions = TALLOC_REALLOC_ARRAY(tmp_ctx, sessions,
dm_sessid_t, nsessions);
if (new_sessions == NULL) {
talloc_free(tmp_ctx);
/* No session already defined. */
if (ctx->session == DM_NO_SESSION) {
- err = dm_create_session(DM_NO_SESSION,
+ err = dm_create_session(DM_NO_SESSION,
session_name,
&ctx->session);
if (err < 0) {
set_effective_capability(DMAPI_ACCESS_CAPABILITY);
}
- /*
- Note that we never end the DMAPI session. It gets re-used if possiblie.
+ /*
+ Note that we never end the DMAPI session. It gets re-used if possiblie.
DMAPI session is a kernel resource that is usually lives until server reboot
and doesn't get destroed when an application finishes.
return (void *)&dmapi_ctx->session;
}
-
+
/*
dmapi_have_session() must be the first DMAPI call you make in Samba. It will
initialize DMAPI, if available, and tell you if you can get a DMAPI session.
return dmapi_ctx->session != DM_NO_SESSION;
}
-/*
+/*
only call this when exiting from master smbd process. DMAPI sessions
are long-lived kernel resources we ought to share across smbd processes.
However, we must free them when all smbd processes are finished to
}
-/*
- This is default implementation of dmapi_file_flags() that is
+/*
+ This is default implementation of dmapi_file_flags() that is
called from VFS is_offline() call to know whether file is offline.
For GPFS-specific version see modules/vfs_tsmsm.c. It might be
that approach on quering existence of a specific attribute that
- is used in vfs_tsmsm.c will work with other DMAPI-based HSM
+ is used in vfs_tsmsm.c will work with other DMAPI-based HSM
implementations as well.
*/
uint32 dmapi_file_flags(const char * const path)
-/*
+/*
Unix SMB/CIFS implementation.
dos mode handling functions
Copyright (C) Andrew Tridgell 1992-1998
Base permission for files:
if creating file and inheriting (i.e. parent_dir != NULL)
apply read/write bits from parent directory.
- else
+ else
everybody gets read bit set
dos readonly is represented in unix by removing everyone's write bit
dos archive is represented in unix by the user's execute bit
/* Clear "result" */
result = 0;
TALLOC_FREE(smb_fname_parent);
- }
+ }
if (IS_DOS_DIR(dosmode)) {
/* We never make directories read only for the owner as under DOS a user
result |= dir_mode;
} else {
/* Provisionally add all 'x' bits */
- result |= (S_IXUSR | S_IXGRP | S_IXOTH);
+ result |= (S_IXUSR | S_IXGRP | S_IXOTH);
/* Apply directory mask */
result &= lp_dir_mask(SNUM(conn));
/* Add in force bits */
result |= lp_force_dir_mode(SNUM(conn));
}
- } else {
+ } else {
if (lp_map_archive(SNUM(conn)) && IS_DOS_ARCHIVE(dosmode))
result |= S_IXUSR;
result |= S_IXGRP;
if (lp_map_hidden(SNUM(conn)) && IS_DOS_HIDDEN(dosmode))
- result |= S_IXOTH;
+ result |= S_IXOTH;
if (dir_mode) {
/* Inherit 666 component of parent directory mode */
result |= aSYSTEM;
if (MAP_HIDDEN(conn) && ((smb_fname->st.st_ex_mode & S_IXOTH) != 0))
- result |= aHIDDEN;
+ result |= aHIDDEN;
if (S_ISDIR(smb_fname->st.st_ex_mode))
result = aDIR | (result & aRONLY);
unixmode |= tmp;
}
- /* if we previously had any w bits set then leave them alone
+ /* if we previously had any w bits set then leave them alone
whilst adding in the new w bits, if the new mode is not rdonly */
if (!IS_DOS_READONLY(dosmode)) {
unixmode |= (smb_fname->st.st_ex_mode & (S_IWUSR|S_IWGRP|S_IWOTH));
/* Don't update the time on read-only shares */
/* We need this as set_filetime (which can be called on
close and other paths) can end up calling this function
- without the NEED_WRITE protection. Found by :
+ without the NEED_WRITE protection. Found by :
Leo Weppelman <leo@wau.mis.ah.nl>
*/
-/*
+/*
Unix SMB/CIFS implementation.
error packet handling
Copyright (C) Andrew Tridgell 1992-1998
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
/* From lib/error.c */
extern struct unix_error_map unix_dos_nt_errmap[];
SSVAL(outbuf,smb_flg2, SVAL(outbuf,smb_flg2)&~FLAGS2_32_BIT_ERROR_CODES);
SSVAL(outbuf,smb_rcls,eclass);
- SSVAL(outbuf,smb_err,ecode);
+ SSVAL(outbuf,smb_err,ecode);
DEBUG(3,("error packet at %s(%d) cmd=%d (%s) eclass=%d ecode=%d\n",
file, line,
-/*
+/*
Unix SMB/CIFS implementation.
FAKE FILE suppport, for faking up special files windows want access to
Copyright (C) Stefan (metze) Metzmacher 2003
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
}
fsp->fake_file_handle = init_fake_file_handle(fake_file_type);
-
+
if (fsp->fake_file_handle==NULL) {
file_free(req, fsp);
return NT_STATUS_NO_MEMORY;
-/*
+/*
Unix SMB/Netbios implementation.
Version 1.9.
read/write to a files_struct
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jeremy Allison 2000-2002. - write cache.
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
static bool setup_write_cache(files_struct *, SMB_OFF_T);
bool cache_flush_needed = False;
if ((pos >= wcp->offset) && (pos <= wcp->offset + wcp->data_size)) {
-
+
/* ASCII art.... JRA.
+--------------+-----
| Data to write |
+-------------------+
- */
+ */
/*
* Start of write overlaps or abutts the existing data.
write_path = 1;
- } else if ((pos < wcp->offset) && (pos + n > wcp->offset) &&
+ } else if ((pos < wcp->offset) && (pos + n > wcp->offset) &&
(pos + n <= wcp->offset + wcp->alloc_size)) {
/* ASCII art.... JRA.
| Data to write |
+-------------------+
- */
+ */
/*
* End of write overlaps the existing data.
write_path = 2;
- } else if ( (pos >= wcp->file_size) &&
+ } else if ( (pos >= wcp->file_size) &&
(wcp->offset + wcp->data_size == wcp->file_size) &&
- (pos > wcp->offset + wcp->data_size) &&
+ (pos > wcp->offset + wcp->data_size) &&
(pos < wcp->offset + wcp->alloc_size) ) {
/* ASCII art.... JRA.
| Data to write |
+-------------------+
- */
+ */
/*
* Non-contiguous write part of which fits within
*/
- /*
+ /*
* Write is bigger than buffer, or there is no overlap on the
* low or high ends.
*/
total_written += n;
return total_written; /* .... that's a write :) */
}
-
+
return total_written;
}
NTSTATUS sync_file(connection_struct *conn, files_struct *fsp, bool write_through)
{
- if (fsp->fh->fd == -1)
+ if (fsp->fh->fd == -1)
return NT_STATUS_INVALID_HANDLE;
if (lp_strict_sync(SNUM(conn)) &&
/*
* The stat failed. Could be ok as it could be
- * a new file.
- */
+ * a new file.
+ */
if (errno == ENOTDIR || errno == ELOOP) {
status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
if (mangle_is_mangled(start, conn->params)
&& mangle_lookup_name_from_8_3(ctx,
- start,
+ start,
&unmangled,
conn->params)) {
char *tmp;
-/*
+/*
Unix SMB/CIFS implementation.
Files[] structure handling
Copyright (C) Andrew Tridgell 1998
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#define VALID_FNUM(fnum) (((fnum) >= 0) && ((fnum) < real_max_open_files))
if (fsp->print_file) {
return fsp;
}
- }
+ }
return NULL;
}
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#if defined(WITH_AIO)
struct aio_extra *aio_list_head = NULL;
-/*
+/*
Unix SMB/CIFS implementation.
Inter-process communication and named pipe handling
Copyright (C) Andrew Tridgell 1992-1998
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#define NERR_notsupported 50
copies parameters and data, as needed, into the smb buffer
*both* the data and params sections should be aligned. this
- is fudged in the rpc pipes by
+ is fudged in the rpc pipes by
at present, only the data section is. this may be a possible
cause of some of the ipc problems being experienced. lkcl26dec97
}
/****************************************************************************
- WaitNamedPipeHandleState
+ WaitNamedPipeHandleState
****************************************************************************/
static void api_WNPHS(connection_struct *conn, struct smb_request *req,
/****************************************************************************
- SetNamedPipeHandleState
+ SetNamedPipeHandleState
****************************************************************************/
static void api_SNPHS(connection_struct *conn, struct smb_request *req,
}
/* Get the file handle and hence the file name. */
- /*
+ /*
* NB. The setup array has already been transformed
* via SVAL and so is in host byte order.
*/
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBtrans);
return;
- }
+ }
/* null-terminate the slack space */
memset(&state->param[state->total_param], 0, 100);
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBtrans);
return;
- }
+ }
for (i=0;i<state->setup_count;i++) {
state->setup[i] = SVAL(req->vwv + 14 + i, 0);
-/*
+/*
Unix SMB/CIFS implementation.
Inter-process communication and named pipe handling
Copyright (C) Andrew Tridgell 1992-1998
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../librpc/gen_ndr/cli_samr.h"
#include "../librpc/gen_ndr/cli_spoolss.h"
#include "../librpc/gen_ndr/srv_samr.h"
int buflen; /* remaining size for fixed part; on init: length of base */
int subcount; /* count of substructures */
char *structbuf; /* pointer into buffer for remaining fixed part */
- int stringlen; /* remaining size for variable part */
+ int stringlen; /* remaining size for variable part */
char *stringbuf; /* pointer into buffer for remaining variable part */
int neededlen; /* total needed size */
int usedlen; /* total used size (usedlen <= neededlen and usedlen <= buflen) */
#define RAP_QUEUE_STATUS_PAUSED 1
#define RAP_QUEUE_STATUS_ERROR 2
-/* turn a print job status into a on the wire status
+/* turn a print job status into a on the wire status
*/
static int printj_status(int v)
{
return 0;
}
-/* turn a print queue status into a on the wire status
+/* turn a print queue status into a on the wire status
*/
static int printq_status(int v)
{
Respond to the DosPrintQInfo command with a level of 52
This is used to get printer driver information for Win9x clients
********************************************************************/
-static void fill_printq_info_52(connection_struct *conn, int snum,
+static void fill_printq_info_52(connection_struct *conn, int snum,
struct pack_desc* desc, int count )
{
int i;
NT_PRINTER_INFO_LEVEL *printer = NULL;
if ( !W_ERROR_IS_OK(get_a_printer( NULL, &printer, 2, lp_servicename(snum))) ) {
- DEBUG(3,("fill_printq_info_52: Failed to lookup printer [%s]\n",
+ DEBUG(3,("fill_printq_info_52: Failed to lookup printer [%s]\n",
lp_servicename(snum)));
goto err;
}
if (!W_ERROR_IS_OK(get_a_printer_driver(talloc_tos(), &driver, printer->info_2->drivername,
"Windows 4.0", 0)) )
{
- DEBUG(3,("fill_printq_info_52: Failed to lookup driver [%s]\n",
+ DEBUG(3,("fill_printq_info_52: Failed to lookup driver [%s]\n",
printer->info_2->drivername));
goto err;
}
static void fill_printq_info(connection_struct *conn, int snum, int uLevel,
- struct pack_desc* desc,
- int count, print_queue_struct* queue,
- print_status_struct* status)
+ struct pack_desc* desc,
+ int count, print_queue_struct* queue,
+ print_status_struct* status)
{
switch (uLevel) {
case 1:
ZERO_STRUCT(driver);
if ( !W_ERROR_IS_OK(get_a_printer( NULL, &printer, 2, lp_servicename(snum))) ) {
- DEBUG(3,("get_printerdrivernumber: Failed to lookup printer [%s]\n",
+ DEBUG(3,("get_printerdrivernumber: Failed to lookup printer [%s]\n",
lp_servicename(snum)));
goto done;
}
if (!W_ERROR_IS_OK(get_a_printer_driver(talloc_tos(), &driver, printer->info_2->drivername,
"Windows 4.0", 0)) )
{
- DEBUG(3,("get_printerdrivernumber: Failed to lookup driver [%s]\n",
+ DEBUG(3,("get_printerdrivernumber: Failed to lookup driver [%s]\n",
printer->info_2->drivername));
goto done;
}
return False;
}
break;
- default:
+ default:
return False;
}
return True;
number of entries.
******************************************************************/
-static int get_server_info(uint32 servertype,
+static int get_server_info(uint32 servertype,
struct srv_info_struct **servers,
const char *domain)
{
ok = False;
}
- if ((servertype & SV_TYPE_DOMAIN_ENUM) !=
+ if ((servertype & SV_TYPE_DOMAIN_ENUM) !=
(s->type & SV_TYPE_DOMAIN_ENUM)) {
DEBUG(4,("s: dom mismatch "));
ok = False;
Fill in a server info structure.
******************************************************************/
-static int fill_srv_info(struct srv_info_struct *service,
- int uLevel, char **buf, int *buflen,
+static int fill_srv_info(struct srv_info_struct *service,
+ int uLevel, char **buf, int *buflen,
char **stringbuf, int *stringspace, char *baseaddr)
{
int struct_len;
static bool api_RNetServerEnum2(connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
- int mdrcnt, int mprcnt, char **rdata,
+ int mdrcnt, int mprcnt, char **rdata,
char **rparam, int *rdata_len, int *rparam_len)
{
char *str1 = get_safe_str_ptr(param, tpscnt, param, 2);
}
/* If someone sets SV_TYPE_LOCAL_LIST_ONLY but hasn't set
- any other bit (they may just set this bit on its own) they
- want all the locally seen servers. However this bit can be
- set on its own so set the requested servers to be
+ any other bit (they may just set this bit on its own) they
+ want all the locally seen servers. However this bit can be
+ set on its own so set the requested servers to be
ALL - DOMAIN_ENUM. */
if ((servertype & SV_TYPE_LOCAL_LIST_ONLY) && !(servertype & SV_TYPE_DOMAIN_ENUM)) {
static bool api_RNetGroupGetUsers(connection_struct *conn, uint16 vuid,
char *param, int tpscnt,
char *data, int tdscnt,
- int mdrcnt, int mprcnt, char **rdata,
+ int mdrcnt, int mprcnt, char **rdata,
char **rparam, int *rdata_len, int *rparam_len)
{
char *str1 = get_safe_str_ptr(param,tpscnt,param,2);
}
static int fill_share_info(connection_struct *conn, int snum, int uLevel,
- char** buf, int* buflen,
- char** stringbuf, int* stringspace, char* baseaddr)
+ char** buf, int* buflen,
+ char** stringbuf, int* stringspace, char* baseaddr)
{
int struct_len;
char* p;
return False;
}
- /* parameters
+ /* parameters
* W-> resume context (number of users to skip)
- * r -> return parameter pointer to receive buffer
+ * r -> return parameter pointer to receive buffer
* L -> length of receive buffer
* e -> return parameter number of entries
* h -> return parameter total number of users
if (!*rparam) {
return False;
}
- SSVAL(*rparam, 0, errflags);
- SSVAL(*rparam, 2, 0); /* converter word */
+ SSVAL(*rparam, 0, errflags);
+ SSVAL(*rparam, 2, 0); /* converter word */
SSVAL(*rparam, 4, num_groups); /* is this right?? */
SSVAL(*rparam, 6, resume_context+num_groups); /* is this right?? */
by NT in a "net time" operation,
it seems to ignore the one below */
- /* the client expects to get localtime, not GMT, in this bit
+ /* the client expects to get localtime, not GMT, in this bit
(I think, this needs testing) */
t = localtime(&unixdate);
if (!t) {
}
memset((char *)pass1,'\0',sizeof(fstring));
- memset((char *)pass2,'\0',sizeof(fstring));
+ memset((char *)pass2,'\0',sizeof(fstring));
return(True);
}
/****************************************************************************
delete a print job
- Form: <W> <>
+ Form: <W> <>
****************************************************************************/
static bool api_RDosPrintJobDel(connection_struct *conn,uint16 vuid,
rpccli_spoolss_ClosePrinter(cli, mem_ctx, &handle, NULL);
}
- SSVAL(*rparam,0,errcode);
+ SSVAL(*rparam,0,errcode);
SSVAL(*rparam,2,0); /* converter word */
return(True);
set the property of a print job (undocumented?)
? function = 0xb -> set name of print job
? function = 0x6 -> move print job up/down
- Form: <WWsTP> <WWzWWDDzzzzzzzzzzlz>
- or <WWsTP> <WB21BB16B10zWWzDDz>
+ Form: <WWsTP> <WWzWWDDzzzzzzzzzzlz>
+ or <WWsTP> <WB21BB16B10zWWzDDz>
****************************************************************************/
static int check_printjob_info(struct pack_desc* desc,
*rdata_len = 0;
/* check it's a supported varient */
- if ((strcmp(str1,"WWsTP")) ||
+ if ((strcmp(str1,"WWsTP")) ||
(!check_printjob_info(&desc,uLevel,str2)))
return(False);
switch (function) {
case 0x6:
- /* change job place in the queue,
+ /* change job place in the queue,
data gives the new place */
place = SVAL(data,0);
if (print_job_set_place(sharename, jobid, place)) {
}
break;
- case 0xb:
+ case 0xb:
/* change print job name, data gives the name */
if (print_job_set_name(sharename, jobid, data)) {
errcode=NERR_Success;
if (uLevel != 20) {
srvstr_push(NULL, 0, p,global_myname(),16,
STR_ASCII|STR_UPPER|STR_TERMINATE);
- }
+ }
p += 16;
if (uLevel > 0) {
struct srv_info_struct *servers=NULL;
get info about a user
struct user_info_11 {
- char usri11_name[21]; 0-20
- char usri11_pad; 21
- char *usri11_comment; 22-25
+ char usri11_name[21]; 0-20
+ char usri11_pad; 21
+ char *usri11_comment; 22-25
char *usri11_usr_comment; 26-29
unsigned short usri11_priv; 30-31
unsigned long usri11_auth_flags; 32-35
****************************************************************************/
-#define usri11_name 0
+#define usri11_name 0
#define usri11_pad 21
#define usri11_comment 22
#define usri11_usr_comment 26
#define USER_PRIV_USER 1
#define USER_PRIV_ADMIN 2
-#define AF_OP_PRINT 0
+#define AF_OP_PRINT 0
#define AF_OP_COMM 1
#define AF_OP_SERVER 2
#define AF_OP_ACCOUNTS 3
return False; /* defined only for uLevel 0,1,2 */
}
- if (!check_printjob_info(&desc,uLevel,str2)) {
+ if (!check_printjob_info(&desc,uLevel,str2)) {
return False;
}
return False;
}
if (id == NULL || strcmp(desc->format,id) != 0) {
- DEBUG(0,("check_printdest_info: invalid string %s\n",
+ DEBUG(0,("check_printdest_info: invalid string %s\n",
id ? id : "<NULL>" ));
return False;
}
desc.base = *rdata;
desc.buflen = mdrcnt;
- if (init_package(&desc,queuecnt,0)) {
+ if (init_package(&desc,queuecnt,0)) {
succnt = 0;
n = 0;
for (i = 0; i < services; i++) {
{NULL, -1, api_Unsupported}
/* The following RAP calls are not implemented by Samba:
- RAP_WFileEnum2 - anon not OK
+ RAP_WFileEnum2 - anon not OK
*/
};
-/*
+/*
Unix SMB/CIFS implementation.
byte range locking code
Updated to handle range splits/merges.
Copyright (C) Andrew Tridgell 1992-2000
Copyright (C) Jeremy Allison 1992-2000
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
(unsigned int)pls->context.smbpid,
(unsigned int)pls->context.tid,
procid_str(talloc_tos(), &pls->context.pid) ));
-
+
DEBUG(10,("start = %.0f, size = %.0f, fnum = %d, %s %s\n",
(double)pls->start,
(double)pls->size,
See if two locking contexts are equal.
****************************************************************************/
-bool brl_same_context(const struct lock_context *ctx1,
+bool brl_same_context(const struct lock_context *ctx1,
const struct lock_context *ctx2)
{
return (procid_equal(&ctx1->pid, &ctx2->pid) &&
See if lock2 can be added when lock1 is in place.
****************************************************************************/
-static bool brl_conflict(const struct lock_struct *lck1,
+static bool brl_conflict(const struct lock_struct *lck1,
const struct lock_struct *lck2)
{
/* Ignore PENDING locks. */
}
return brl_overlap(lck1, lck2);
-}
+}
/****************************************************************************
See if lock2 can be added when lock1 is in place - when both locks are POSIX
know already match.
****************************************************************************/
-static bool brl_conflict_posix(const struct lock_struct *lck1,
- const struct lock_struct *lck2)
+static bool brl_conflict_posix(const struct lock_struct *lck1,
+ const struct lock_struct *lck2)
{
#if defined(DEVELOPER)
SMB_ASSERT(lck1->lock_flav == POSIX_LOCK);
/* One is read, the other write, or the context is different,
do they overlap ? */
return brl_overlap(lck1, lck2);
-}
+}
#if ZERO_ZERO
-static bool brl_conflict1(const struct lock_struct *lck1,
+static bool brl_conflict1(const struct lock_struct *lck1,
const struct lock_struct *lck2)
{
if (IS_PENDING_LOCK(lck1->lock_type) || IS_PENDING_LOCK(lck2->lock_type))
lck2->start >= (lck1->start + lck1->size)) {
return False;
}
-
+
return True;
-}
+}
#endif
/****************************************************************************
if (IS_PENDING_LOCK(lck1->lock_type) || IS_PENDING_LOCK(lck2->lock_type))
return False;
- if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK)
+ if (lck1->lock_type == READ_LOCK && lck2->lock_type == READ_LOCK)
return False;
/* POSIX flavour locks never conflict here - this is only called
}
return brl_overlap(lck1, lck2);
-}
+}
/****************************************************************************
Check if an unlock overlaps a pending lock.
Compare two locks for sorting.
****************************************************************************/
-static int lock_compare(const struct lock_struct *lck1,
+static int lock_compare(const struct lock_struct *lck1,
const struct lock_struct *lck2)
{
if (lck1->start != lck2->start) {
return brl_lock_failed(fsp,plock,blocking_lock);
}
#if ZERO_ZERO
- if (plock->start == 0 && plock->size == 0 &&
+ if (plock->start == 0 && plock->size == 0 &&
locks[i].size == 0) {
break;
}
uint32 smbpid,
struct server_id pid,
br_off start,
- br_off size,
+ br_off size,
enum brl_type lock_type,
enum brl_flavour lock_flav,
bool blocking_lock,
/* Actually delete the lock. */
if (i < br_lck->num_locks - 1) {
- memmove(&locks[i], &locks[i+1],
+ memmove(&locks[i], &locks[i+1],
sizeof(*locks)*((br_lck->num_locks-1) - i));
}
uint32 smbpid,
struct server_id pid,
br_off start,
- br_off size,
+ br_off size,
enum brl_type lock_type,
enum brl_flavour lock_flav)
{
uint32 *psmbpid,
struct server_id pid,
br_off *pstart,
- br_off *psize,
+ br_off *psize,
enum brl_type *plock_type,
enum brl_flavour lock_flav)
{
if (exlock->lock_flav == WINDOWS_LOCK) {
conflict = brl_conflict(exlock, &lock);
- } else {
+ } else {
conflict = brl_conflict_posix(exlock, &lock);
}
if (conflict) {
*psmbpid = exlock->context.smbpid;
- *pstart = exlock->start;
+ *pstart = exlock->start;
*psize = exlock->size;
- *plock_type = exlock->lock_type;
+ *plock_type = exlock->lock_type;
return NT_STATUS_LOCK_NOT_GRANTED;
}
}
if (i < br_lck->num_locks - 1) {
/* Found this particular pending lock - delete it */
- memmove(&locks[i], &locks[i+1],
+ memmove(&locks[i], &locks[i+1],
sizeof(*locks)*((br_lck->num_locks-1) - i));
}
locks_copy = (struct lock_struct *)TALLOC_MEMDUP(br_lck, locks, br_lck->num_locks * sizeof(struct lock_struct));
if (!locks_copy) {
smb_panic("brl_close_fnum: talloc failed");
- }
- } else {
+ }
+ } else {
locks_copy = NULL;
}
/* found it - delete it */
if (br_lck->num_locks > 1 && i < br_lck->num_locks - 1) {
- memmove(&locks[i], &locks[i+1],
+ memmove(&locks[i], &locks[i+1],
sizeof(*locks)*((br_lck->num_locks-1) - i));
}
br_lck->num_locks--;
memcpy(br_lck->lock_data, data.dptr, data.dsize);
}
-
+
if (!fsp->lockdb_clean) {
int orig_num_locks = br_lck->num_locks;
-/*
+/*
Unix SMB/CIFS implementation.
Locking functions
Copyright (C) Andrew Tridgell 1992-2000
Copyright (C) Jeremy Allison 1992-2006
Copyright (C) Volker Lendecke 2005
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
lock_pid,
procid_self(),
offset,
- count,
+ count,
lock_type,
lock_flav,
blocking_lock,
{
bool ok = False;
struct byte_range_lock *br_lck = NULL;
-
+
if (!fsp->can_lock) {
return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
}
-
+
if (!lp_locking(fsp->conn->params)) {
return NT_STATUS_OK;
}
-
+
DEBUG(10,("do_unlock: unlock start=%.0f len=%.0f requested for fnum %d file %s\n",
(double)offset, (double)count, fsp->fnum,
fsp_str_dbg(fsp)));
offset,
count,
lock_flav);
-
+
TALLOC_FREE(br_lck);
if (!ok) {
return fsp->is_directory ?
NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
}
-
+
if (!lp_locking(fsp->conn->params)) {
return NT_STATUS_DOS(ERRDOS, ERRcancelviolation);
}
}
lck->share_modes = NULL;
-
+
if (lck->num_share_modes != 0) {
if (dbuf.dsize < (sizeof(struct locking_data) +
sizeof(struct share_mode_entry)))) {
smb_panic("parse_share_modes: buffer too short");
}
-
+
lck->share_modes = (struct share_mode_entry *)
TALLOC_MEMDUP(lck,
dbuf.dptr+sizeof(struct locking_data),
}
/*******************************************************************
- Check if two share mode entries are identical, ignoring oplock
+ Check if two share mode entries are identical, ignoring oplock
and mid info and desired_access. (Removed paranoia test - it's
not automatically a logic error if they are identical. JRA.)
********************************************************************/
if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
/*
* Going from exclusive or batch,
- * we always go through FAKE_LEVEL_II
- * first.
- */
+ * we always go through FAKE_LEVEL_II
+ * first.
+ */
e->op_type = FAKE_LEVEL_II_OPLOCK;
} else {
e->op_type = NO_OPLOCK;
bool set_delete_on_close(files_struct *fsp, bool delete_on_close, const UNIX_USER_TOKEN *tok)
{
struct share_mode_lock *lck;
-
+
DEBUG(10,("set_delete_on_close: %s delete on close flag for "
"fnum = %d, file %s\n",
delete_on_close ? "Adding" : "Removing", fsp->fnum,
-/*
+/*
Unix SMB/CIFS implementation.
Locking functions
Copyright (C) Jeremy Allison 1992-2006
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*offset_out = offset;
*count_out = count;
-
+
return True;
}
struct lock_ref_count_key {
struct file_id id;
char r;
-};
+};
/*******************************************************************
Form a static locking key for a dev/inode pair for the lock ref count
}
l_curr = ul_next;
-
+
} else if ( (l_curr->start >= lock->start) &&
(l_curr->start < lock->start + lock->size) &&
(l_curr->start + l_curr->size > lock->start + lock->size) ) {
(double)l_curr->start, (double)l_curr->size ));
l_curr = l_curr->next;
-
+
} else if ( (l_curr->start < lock->start) &&
(l_curr->start + l_curr->size > lock->start + lock->size) ) {
/*
(double)l_new->start, (double)l_new->size ));
/*
- * Add into the dlink list after the l_curr point - NOT at lhead.
+ * Add into the dlink list after the l_curr point - NOT at lhead.
*/
DLIST_ADD_AFTER(lhead, l_new, l_curr);
* ------------------------------------------------------------------------
* WRITE LOCK : start = 2, len = 10
* READ LOCK: start =0, len = 10 - FAIL
- * READ LOCK : start = 0, len = 14
+ * READ LOCK : start = 0, len = 14
* READ LOCK: start =0, len = 10 - FAIL
* UNLOCK : start = 2, len = 10
* READ LOCK: start =0, len = 10 - OK
* Under POSIX, the same sequence in steps 1 and 2 would not be reference counted, but
* would leave a single read lock over the 0-14 region.
*/
-
+
if ((l_ctx = talloc_init("set_posix_lock")) == NULL) {
DEBUG(0,("set_posix_lock_windows_flavour: unable to init talloc context.\n"));
return False;
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
/* this allows us to add more mangling backends */
static const struct {
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
/* -------------------------------------------------------------------------- **
* Other stuff...
-/*
+/*
Unix SMB/CIFS implementation.
new hash based name mangling implementation
Copyright (C) Andrew Tridgell 2002
Copyright (C) Simo Sorce 2002
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
This file deliberately uses non-multibyte string functions in many places. This
is *not* a mistake. This code is multi-byte safe, but it gets this property
- through some very subtle knowledge of the way multi-byte strings are encoded
+ through some very subtle knowledge of the way multi-byte strings are encoded
and the fact that this mangling algorithm only supports ascii characters in
8.3 names.
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#if 1
#define M_DEBUG(level, x) DEBUG(level, x)
{ "AUX", "LOCK$", "CON", "COM1", "COM2", "COM3", "COM4",
"LPT1", "LPT2", "LPT3", "NUL", "PRN", NULL };
-/*
+/*
hash a string of the specified length. The string does not need to be
- null terminated
+ null terminated
this hash needs to be fast with a low collision rate (what hash doesn't?)
*/
/* note that we force it to a 31 bit hash, to keep within the limits
of the 36^6 mangle space */
- return value & ~0x80000000;
+ return value & ~0x80000000;
}
/*
}
-/*
+/*
determine if a string is possibly in a mangled format, ignoring
- case
+ case
In this algorithm, mangled names use only pure ascii characters (no
- multi-byte) so we can avoid doing a UCS2 conversion
+ multi-byte) so we can avoid doing a UCS2 conversion
*/
static bool is_mangled_component(const char *name, size_t len)
{
}
}
}
-
+
/* check lead characters */
for (i=0;i<mangle_prefix;i++) {
if (! FLAG_CHECK(name[i], FLAG_ASCII)) {
return False;
}
}
-
+
/* check rest of hash */
if (! FLAG_CHECK(name[7], FLAG_BASECHAR)) {
return False;
-/*
+/*
determine if a string is possibly in a mangled format, ignoring
- case
+ case
In this algorithm, mangled names use only pure ascii characters (no
- multi-byte) so we can avoid doing a UCS2 conversion
+ multi-byte) so we can avoid doing a UCS2 conversion
NOTE! This interface must be able to handle a path with unix
directory separators. It should return true if any component is
return True;
}
}
-
+
/* and the last part ... */
return is_mangled_component(s,strlen(s));
}
-/*
+/*
see if a filename is an allowable 8.3 name to return to the client.
Note this is not testing if this is a valid Samba mangled name, so
the rules are different for is_mangled.
}
/*
- the main forward mapping function, which converts a long filename to
+ the main forward mapping function, which converts a long filename to
a 8.3 name
if cache83 is not set then we don't cache the result
-/*
+/*
Unix SMB/CIFS implementation.
Username handling
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jeremy Allison 1997-2001.
Copyright (C) Volker Lendecke 2006
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
/*******************************************************************
Map a username from a dos name to a unix name by looking in the username
-/*
+/*
Unix SMB/CIFS implementation.
SMB messaging
Copyright (C) Andrew Tridgell 1992-1998
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
extern userdom_struct current_user_info;
-/*
+/*
* Conversion table for CP437 charset also known as IBM437
*
* Copyright (C) Alexander Bokovoy 2003
*
- * Conversion tables are generated using GNU libc 2.2.5's
+ * Conversion tables are generated using GNU libc 2.2.5's
* localedata/charmaps/IBM437 table and source/script/gen-8bit-gap.sh script
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-/*
+/*
* Conversion table for CP850 charset also known as IBM850.
*
* Copyright (C) Alexander Bokovoy 2003
*
- * Conversion tables are generated using GNU libc 2.2.5's
+ * Conversion tables are generated using GNU libc 2.2.5's
* localedata/charmaps/IBM850 table and source/script/gen-8bit-gap.sh script
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
};
SMB_GENERATE_CHARSET_MODULE_8_BIT_GAP(CP850)
-
The patch basically moves the GPFS-ACL functionalities into the new GPFS VFS module( vfs_gpfs ).
-Please read SAMBA_3_0/source/modules/README.nfs4acls.txt - generalised README file on Samba support for NFS4-ACLS.
+Please read SAMBA_3_0/source/modules/README.nfs4acls.txt - generalised README file on Samba support for NFS4-ACLS.
This README file is specific for GPFS only.
Configuring GPFS ACL support
===============================
Binary: (default install path is [samba]/lib/vfs/)
-- gpfs.so
+- gpfs.so
Its compiled by default, no additional configure option needed.
Eg: Prent directory is set to have 2 ACES - full access for owner and everyone
-Default ACL for Windows: 2 aces: allow ACE for owner and everyone
+Default ACL for Windows: 2 aces: allow ACE for owner and everyone
Default ACL for GPFS: 6 aces: allow and deny ACEs for owner, group and everyone
-The below mentioned inheritance flags and its combinations are applied only to the owner ACE and not to everyone ACE
+The below mentioned inheritance flags and its combinations are applied only to the owner ACE and not to everyone ACE
"fi"------>File Inherit
"di"------>Directory Inherit
"oi"------>Inherit Only
-
-Parent dir: no inheritance flag set
+
+Parent dir: no inheritance flag set
Windows: index=0: GPFS(special mode): index=0: GPFS(simple mode): index=0:
child File: default acl: 2 aces child file: default acl: 6 aces child file: default acl: 6 aces
child dir: default acl: 2 aces child dir: default acl: 6 aces child dir: default acl: 6 aces
Parent dir: "fi" flag set
Windows: index=1: GPFS(special mode): index=1: GPFS(simple mode): index=1:
-child file: no flag set child file: "fi" flag set child file: default acl: 6 aces
+child file: no flag set child file: "fi" flag set child file: default acl: 6 aces
child dir: "fioi" flag set child dir: "fi" flag set child dir: "fi" flag set
child file: no flag set child file: "fidi" flag set child file: default acl: 6 aces
-Parent dir: "fioi" flag set
+Parent dir: "fioi" flag set
Windows: index=4: GPFS(special mode): index=4: GPFS(simple mode): index=4:
child file: no flag set child file: "fi" flag set child file: default acl: 6 aces
child dir: "fioi" flag set child dir: "fi" flag set child dir: "fi" flag set
===============================
Created: Peter Somogyi, 2006-JUN-06
Last modified: Peter Somogyi, 2006-JUL-20
-Revision no.: 4
+Revision no.: 4
-------------------------------
NFS4 ACL rights are enforced by the OS or filesystem, not by Samba.
The flag INHERITED_ACE is never set (not required, as doesn't do WinNT/98/me, only since Win2k).
-Win2k GUI behaves strangely when detecting inheritance (sometimes it doesn't detect,
+Win2k GUI behaves strangely when detecting inheritance (sometimes it doesn't detect,
but after adding an ace it shows that - it's some GUI error).
Unknown (unmappable) SIDs are not accepted.
-/*
+/*
Unix SMB/CIFS implementation.
Samba charset module for Mac OS X/Darwin
Copyright (C) Benjamin Riefenstahl 2003
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
* Add a converted null byte, if the CFString conversions
* prevented that until now.
*/
- if (0 == (*inbuf)[*inbytesleft-1] &&
+ if (0 == (*inbuf)[*inbytesleft-1] &&
(0 != (*outbuf)[outsize*2-1] || 0 != (*outbuf)[outsize*2-2])) {
if ((outsize*2+2) > *outbytesleft) {
-/*
+/*
Unix SMB/CIFS implementation.
Samba module with developer tools
Copyright (C) Andrew Tridgell 2001
Copyright (C) Jelmer Vernooij 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 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
int i;
int done = 0;
for (i=0;weird_table[i].from;i++) {
- if (strncmp((*inbuf),
- weird_table[i].to,
+ if (strncmp((*inbuf),
+ weird_table[i].to,
weird_table[i].len) == 0) {
if (*inbytesleft < weird_table[i].len) {
DEBUG(0,("ERROR: truncated weird string\n"));
errno = E2BIG;
return -1;
}
-
+
return 0;
}
DEBUG(0,("No room for weird character\n"));
/* smb_panic("weird_push"); */
} else {
- memcpy(*outbuf, weird_table[i].to,
+ memcpy(*outbuf, weird_table[i].to,
weird_table[i].len);
(*inbytesleft) -= 2;
(*outbytesleft) -= weird_table[i].len;
errno = E2BIG;
return -1;
}
-
+
return ir_count;
}
/* Include this file down here because bison inserts code above which
may define-away `const'. We want the prototype for get_date to have
the same signature as the function definition. */
-#include "modules/getdate.h"
+#include "fileserver/modules/getdate.h"
#ifndef gmtime
struct tm *gmtime (const time_t *);
return 0;
}
#endif /* defined TEST */
-
/* Include this file down here because bison inserts code above which
may define-away `const'. We want the prototype for get_date to have
the same signature as the function definition. */
-#include "modules/getdate.h"
+#include "fileserver/modules/getdate.h"
#ifndef gmtime
struct tm *gmtime (const time_t *);
-/*
+/*
* Unix SMB/CIFS implementation.
* Provide a connection to GPFS specific features
* Copyright (C) Volker Lendecke 2005
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
if (allow == GPFS_SHARE_NONE) {
DEBUG(10, ("special case am=no_access:%x\n",access_mask));
}
- else {
+ else {
deny |= (share_access & FILE_SHARE_WRITE) ?
0 : GPFS_DENY_WRITE;
deny |= (share_access & (FILE_SHARE_READ)) ?
}
}
-/*
+/*
* Find 2 NFS4 who-special ACE property (non-copy!!!)
* match nonzero if "special" and who is equal
* return ace if found matching; otherwise NULL
{
static struct db_context *mapping_db = NULL;
TDB_DATA data;
-
+
if (mapping_db == NULL) {
const char *dbname = lp_parm_const_string(
-1, SMBACL4_PARAM_TYPE_NAME, "sidmap", NULL);
-
+
if (dbname == NULL) {
DEBUG(10, ("%s:sidmap not defined\n",
SMBACL4_PARAM_TYPE_NAME));
return False;
}
-
+
become_root();
mapping_db = db_open(NULL, dbname, 0, TDB_DEFAULT,
O_RDONLY, 0600);
unbecome_root();
-
+
if (mapping_db == NULL) {
DEBUG(1, ("could not open sidmap: %s\n",
strerror(errno)));
return False;
}
}
-
+
if (mapping_db->fetch(mapping_db, NULL,
string_term_tdb_data(sid_string_tos(src)),
&data) == -1) {
sid_string_dbg(src)));
return False;
}
-
+
if ((data.dptr == NULL) || (data.dsize <= 0)
|| (data.dptr[data.dsize-1] != '\0')) {
DEBUG(5, ("invalid mapping for SID %s\n",
TALLOC_FREE(data.dptr);
return False;
}
-
+
if (!string_to_sid(dst, (char *)data.dptr)) {
DEBUG(1, ("invalid mapping %s for SID %s\n",
(char *)data.dptr, sid_string_dbg(src)));
}
TALLOC_FREE(data.dptr);
-
+
return True;
}
uid_t uid;
gid_t gid;
DOM_SID sid;
-
+
sid_copy(&sid, &ace_nt->trustee);
-
+
if (!lookup_sid(mem_ctx, &sid, &dom, &name, &type)) {
-
+
DOM_SID mapped;
-
+
if (!nfs4_map_sid(params, &sid, &mapped)) {
DEBUG(1, ("nfs4_acls.c: file [%s]: SID %s "
"unknown\n", filename, sid_string_dbg(&sid)));
errno = EINVAL;
return False;
}
-
+
DEBUG(2, ("nfs4_acls.c: file [%s]: mapped SID %s "
"to %s\n", filename, sid_string_dbg(&sid), sid_string_dbg(&mapped)));
-
+
if (!lookup_sid(mem_ctx, &mapped, &dom,
&name, &type)) {
DEBUG(1, ("nfs4_acls.c: file [%s]: SID %s "
errno = EINVAL;
return False;
}
-
+
sid_copy(&sid, &mapped);
}
-
+
if (type == SID_NAME_USER) {
if (!sid_to_uid(&sid, &uid)) {
DEBUG(1, ("nfs4_acls.c: file [%s]: could not "
sid_string_dbg(&sid)));
return False;
}
-
+
ace_v4->aceFlags |= SMB_ACE4_IDENTIFIER_GROUP;
if (params->mode==e_special && gid==ownerGID) {
#define SMB_ACLTYPE_POSIX 2
#define SMB_ACLTYPE_NFS4 4
-/*
- * Following union captures the identity as
- * used in the NFS4 ACL structures.
+/*
+ * Following union captures the identity as
+ * used in the NFS4 ACL structures.
*/
typedef union _SMB_NFS4_ACEWHOID_T {
uid_t uid; /* User id */
uint32 id;
} SMB_NFS4_ACEWHOID_T;
-typedef struct _SMB_ACE4PROP_T {
+typedef struct _SMB_ACE4PROP_T {
uint32 flags; /* Bit mask defining details of ACE */
/*The following are constants for flags field */
/* #define SMB_ACE4_ID_NOT_VALID 0x00000001 - from aix/jfs2 */
static struct cbrl_event_ops cbrl_ops =
{.cbrl_async_success = onefs_cbrl_async_success,
.cbrl_async_failure = onefs_cbrl_async_failure};
-
+
static void onefs_cbrl_events_handler(struct event_context *ev,
struct fd_event *fde,
uint16_t flags,
/* XXX brl_close_fnum: CBRL will do this automatically. I think this is a NO-OP
* for us, we could add an empty VOP. */
-
#include "onefs.h"
#include "onefs_config.h"
#include "oplock_onefs.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
extern const struct generic_mapping file_generic_mapping;
int fd = smbd_server_fd();
sa_len = sizeof sa;
- if (getpeername(fd, (struct sockaddr *)&sa, &sa_len) == 0 &&
+ if (getpeername(fd, (struct sockaddr *)&sa, &sa_len) == 0 &&
sa.ss_family == AF_INET)
rem_addr = ((struct sockaddr_in *)&sa)->sin_addr.s_addr;
else
if (psd != pdesc_next) {
/* We're returning the blob, throw
- * away the filesystem SD. */
+ * away the filesystem SD. */
TALLOC_FREE(pdesc_next);
} else {
SMB_STRUCT_STAT sbuf;
is_directory ? "directory" : "file",
parent_dir, final_component ));
- /* cd into the parent dir to pin it. */
+ /* cd into the parent dir to pin it. */
ret = SMB_VFS_CHDIR(conn, parent_dir);
if (ret == -1) {
saved_errno = errno;
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_VFS
-#include "modules/vfs_acl_common.c"
+#include "fileserver/modules/vfs_acl_common.c"
static unsigned int ref_count;
static struct db_context *acl_db;
#define DBGC_CLASS DBGC_VFS
/* Pull in the common functions. */
-#include "modules/vfs_acl_common.c"
+#include "fileserver/modules/vfs_acl_common.c"
/*******************************************************************
Pull a security descriptor into a DATA_BLOB from a xattr.
-/*
+/*
* Convert AFS acls to NT acls and vice versa.
*
* Copyright (C) Volker Lendecke, 2003
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
return result;
}
-
+
static struct afs_ace *new_afs_ace(TALLOC_CTX *mem_ctx,
bool positive,
const char *name, uint32 rights)
if (sscanf(p, "%d", &nminus) != 1)
return False;
-
+
DEBUG(10, ("Found %d negative entries\n", nminus));
if ((p = strchr(p, '\n')) == NULL)
uint32 result = 0;
if (rights & PRSFS_READ)
- result |= FILE_READ_DATA | FILE_READ_EA |
+ result |= FILE_READ_DATA | FILE_READ_EA |
FILE_EXECUTE | FILE_READ_ATTRIBUTES |
READ_CONTROL_ACCESS | SYNCHRONIZE_ACCESS;
*nt_rights |= FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY;
if (afs_rights & PRSFS_LOOKUP)
- *nt_rights |= FILE_READ_DATA | FILE_READ_EA |
+ *nt_rights |= FILE_READ_DATA | FILE_READ_EA |
FILE_EXECUTE | FILE_READ_ATTRIBUTES |
READ_CONTROL_ACCESS | SYNCHRONIZE_ACCESS;
{ 0, SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT,
0x00120089, 8 /* l */ },
- /* some stupid workaround for preventing fallbacks */
+ /* some stupid workaround for preventing fallbacks */
{ 0, 0x3, 0x0012019F, 9 /* rl */ },
{ 0, 0x13, PERMS_FULL, 127 /* full */ },
-
+
/* read, delete and execute access plus synchronize */
{ 0, 0x3, 0x001300A9, 9 /* should be rdl, set to rl */},
/* classical read list */
static bool mappable_sid(const DOM_SID *sid)
{
DOM_SID domain_sid;
-
+
if (sid_compare(sid, &global_sid_Builtin_Administrators) == 0)
return True;
return afs_set_nt_acl(handle, fsp, security_info_sent, psd);
}
-static int afsacl_connect(vfs_handle_struct *handle,
- const char *service,
+static int afsacl_connect(vfs_handle_struct *handle,
+ const char *service,
const char *user)
{
const char *spc;
{
struct acl *file_acl = (struct acl *)NULL;
struct smb_acl_t *result = (struct smb_acl_t *)NULL;
-
+
int rc = 0;
uid_t user_id;
return NULL;
/* Get the acl using statacl */
-
+
DEBUG(10,("Entering AIX sys_acl_get_file\n"));
DEBUG(10,("path_p is %s\n",path_p));
file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
-
+
if(file_acl == NULL) {
errno=ENOMEM;
DEBUG(0,("Error in AIX sys_acl_get_file: %d\n",errno));
DEBUG(10,("Got facl and returned it\n"));
-
+
result = aixacl_to_smbacl(file_acl);
SAFE_FREE(file_acl);
return result;
-
+
/*errno = ENOTSUP;
return NULL;*/
}
struct acl *file_acl = (struct acl *)NULL;
struct smb_acl_t *result = (struct smb_acl_t *)NULL;
-
+
int rc = 0;
uid_t user_id;
/* Get the acl using fstatacl */
-
+
DEBUG(10,("Entering AIX sys_acl_get_fd\n"));
DEBUG(10,("fd is %d\n",fsp->fh->fd));
file_acl = (struct acl *)SMB_MALLOC(BUFSIZ);
result = aixacl_to_smbacl(file_acl);
SAFE_FREE(file_acl);
return result;
-
+
/*errno = ENOTSUP;
return NULL;*/
}
{
struct acl *file_acl = NULL;
unsigned int rc;
-
+
file_acl = aixacl_smb_to_aixacl(type, theacl);
if (!file_acl)
return -1;
static int32_t aixacl2_getlen(AIXJFS2_ACL_T *acl, acl_type_t *type)
{
int32_t len;
-
+
if(type->u64 == ACL_NFS4) {
len = acl->jfs2_acl[0].aclLength;
- }
+ }
else {
if(type->u64 == ACL_AIXC) {
len = acl->aixc_acl[0].acl_len;
} else {
DEBUG(0,("aixacl2_getlen:unknown type:%d\n",type->u64));
- return False;
- }
- }
+ return False;
+ }
+ }
DEBUG(10,("aixacl2_getlen:%d\n",len));
return len;
}
SMB4ACL_T **ppacl, bool *pretryPosix)
{
int32_t i;
-
+
AIXJFS2_ACL_T *pacl = NULL;
nfs4_acl_int_t *jfs2_acl = NULL;
nfs4_ace_int_t *jfs2_ace = NULL;
result = set_nt_acl(fsp, security_info_sent, psd);
} else
result = map_nt_error_from_unix(errno); /* query failed */
-
+
return result;
}
{
struct acl_entry *acl_entry;
struct ace_id *idp;
-
+
struct smb_acl_t *result = SMB_MALLOC_P(struct smb_acl_t);
struct smb_acl_entry *ace;
int i;
-
+
if (result == NULL) {
return NULL;
}
ZERO_STRUCTP(result);
-
+
/* Point to the first acl entry in the acl */
acl_entry = file_acl->acl_ext;
-
+
DEBUG(10,("acl_entry is %p\n",(void *)acl_entry));
DEBUG(10,("acl_last(file_acl) id %p\n",(void *)acl_last(file_acl)));
idp = acl_entry->ace_id;
DEBUG(10,("idp->id_data is %d\n",idp->id_data[0]));
-
+
result = SMB_REALLOC(result, sizeof(struct smb_acl_t) +
(sizeof(struct smb_acl_entry) *
(result->count+1)));
errno = ENOMEM;
return NULL;
}
-
+
DEBUG(10,("idp->id_type is %d\n",idp->id_type));
ace = &result->acl[result->count];
-
+
ace->a_type = idp->id_type;
-
+
switch(ace->a_type) {
case ACEID_USER: {
ace->uid = idp->id_data[0];
ace->a_type = SMB_ACL_USER;
break;
}
-
+
case ACEID_GROUP: {
ace->gid = idp->id_data[0];
DEBUG(10,("case ACEID_GROUP ace->gid is %d\n",ace->gid));
break;
default:
DEBUG(0, ("unknown ace->type\n"));
- SAFE_FREE(result);
+ SAFE_FREE(result);
return(0);
}
-
+
result->count++;
ace->a_perm |= (ace->a_perm & S_IRUSR) ? SMB_ACL_READ : 0;
ace->a_perm |= (ace->a_perm & S_IWUSR) ? SMB_ACL_WRITE : 0;
ace->a_perm |= (ace->a_perm & S_IXUSR) ? SMB_ACL_EXECUTE : 0;
DEBUG(10,("ace->a_perm is %d\n",ace->a_perm));
-
+
DEBUG(10,("acl_entry = %p\n",(void *)acl_entry));
DEBUG(10,("The ace_type is %d\n",acl_entry->ace_type));
-
+
acl_entry = acl_nxt(acl_entry);
}
} /* end of if enabled */
DEBUG(0,("Error in AIX sys_acl_get_file is %d\n",errno));
return NULL;
}
-
+
ace = &result->acl[result->count];
-
+
ace->uid = 0;
ace->gid = 0;
DEBUG(10,("ace->uid = %d\n",ace->uid));
-
+
switch(i) {
case 2:
ace->a_perm = file_acl->g_access << 6;
ace->a_perm = file_acl->o_access << 6;
ace->a_type = SMB_ACL_OTHER;
break;
-
+
case 1:
ace->a_perm = file_acl->u_access << 6;
ace->a_type = SMB_ACL_USER_OBJ;
break;
-
+
default:
return(NULL);
ace->a_perm |= ((ace->a_perm & S_IRUSR) ? SMB_ACL_READ : 0);
ace->a_perm |= ((ace->a_perm & S_IWUSR) ? SMB_ACL_WRITE : 0);
ace->a_perm |= ((ace->a_perm & S_IXUSR) ? SMB_ACL_EXECUTE : 0);
-
+
memcpy(&result->acl[result->count],ace,sizeof(struct smb_acl_entry));
result->count++;
DEBUG(10,("ace->a_perm = %d\n",ace->a_perm));
unsigned int id_type;
unsigned int acl_length;
int i;
-
+
DEBUG(10,("Entering aixacl_smb_to_aixacl\n"));
/* AIX has no default ACL */
if(acltype == SMB_ACL_TYPE_DEFAULT)
}
memset(file_acl,0,BUFSIZ);
-
+
file_acl->acl_len = ACL_SIZ;
file_acl->acl_mode = S_IXACL;
-/*
+/*
* Auditing VFS module for samba. Log selected file operations to syslog
* facility.
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
openlog("smbd_audit", LOG_PID, audit_syslog_facility(handle));
- syslog(audit_syslog_priority(handle), "connect to service %s by user %s\n",
+ syslog(audit_syslog_priority(handle), "connect to service %s by user %s\n",
svc, user);
return 0;
static SMB_STRUCT_DIR *audit_opendir(vfs_handle_struct *handle, const char *fname, const char *mask, uint32 attr)
{
SMB_STRUCT_DIR *result;
-
+
result = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, attr);
syslog(audit_syslog_priority(handle), "opendir %s %s%s\n",
static int audit_mkdir(vfs_handle_struct *handle, const char *path, mode_t mode)
{
int result;
-
+
result = SMB_VFS_NEXT_MKDIR(handle, path, mode);
-
- syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n",
+
+ syslog(audit_syslog_priority(handle), "mkdir %s %s%s\n",
path,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
result = SMB_VFS_NEXT_RMDIR(handle, path);
- syslog(audit_syslog_priority(handle), "rmdir %s %s%s\n",
- path,
+ syslog(audit_syslog_priority(handle), "rmdir %s %s%s\n",
+ path,
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
result = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
- syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n",
+ syslog(audit_syslog_priority(handle), "open %s (fd %d) %s%s%s\n",
smb_fname->base_name, result,
- ((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "",
+ ((flags & O_WRONLY) || (flags & O_RDWR)) ? "for writing " : "",
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
(result < 0) ? "failed: " : "",
(result < 0) ? strerror(errno) : "");
- return result;
+ return result;
}
static int audit_unlink(vfs_handle_struct *handle,
} else {
*out++ = *from++;
}
- }
+ }
*out = '\0';
return to;
}
}
smb_fname_src_tmp->base_name = src_name_mapped;
- smb_fname_dst_tmp->base_name = dst_name_mapped;
+ smb_fname_dst_tmp->base_name = dst_name_mapped;
DEBUG(10, ("converted old name: %s\n",
smb_fname_str_dbg(smb_fname_src_tmp)));
DEBUG(10, ("converted new name: %s\n",
* size of the file before transferring it. With this
* option, we remember that hint, and commit after
* writing in that file position. If the client
- * doesn't declare the size of file, commiting on EOF
+ * doesn't declare the size of file, commiting on EOF
* is not triggered.
*
* = growth Commits after a write operation has made the file
return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, MODULE,
&vfs_commit_fns);
}
-
-
return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, MODULE,
&vfs_crossrename_fns);
}
-
static NTSTATUS vfswrap_notify_watch(vfs_handle_struct *vfs_handle,
struct sys_notify_context *ctx,
struct notify_entry *e,
- void (*callback)(struct sys_notify_context *ctx,
+ void (*callback)(struct sys_notify_context *ctx,
void *private_data,
struct notify_event *ev),
void *private_data, void *handle)
return smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
DEFAULT_VFS_MODULE_NAME, &vfs_default_fns);
}
-
-
-/*
+/*
* Store default Quotas in a specified quota record
*
* Copyright (C) Stefan (metze) Metzmacher 2003
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
* it can be overwrittem when you load the module in
* the 'vfs objects' parameter like this:
* vfs objects = default_quota:myprefix)
- *
+ *
* "<myprefix>:uid" parameter takes a integer argument,
* it specifies the uid of the quota record, that will be taken for
* storing the default USER-quotas.
* it specifies if we should report the stored default quota values,
* also for the user record, or if you should just report NO_LIMIT
* to the windows client for the user specified by the "<prefix>:uid" parameter.
- *
+ *
* - default value: yes (that means to report NO_LIMIT)
* - e.g.: default_quota:uid nolimit = no
- *
+ *
* "<myprefix>:gid" parameter takes a integer argument,
* it's just like "<prefix>:uid" but for group quotas.
* (NOTE: group quotas are not supported from the windows explorer!)
* "<myprefix>:gid nolimit" parameter takes a boolean argument,
* it's just like "<prefix>:uid nolimit" but for group quotas.
* (NOTE: group quotas are not supported from the windows explorer!)
- *
+ *
* - default value: yes (that means to report NO_LIMIT)
* - e.g.: default_quota:uid nolimit = no
*
-/*
+/*
* Expand msdfs targets based on client IP
*
* Copyright (C) Volker Lendecke, 2004
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-/*
+/*
* Auditing VFS module for samba. Log selected file operations to syslog
* facility.
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
{
NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
"extd_audit", &vfs_extd_audit_fns);
-
+
if (!NT_STATUS_IS_OK(ret))
return ret;
} else {
DEBUG(10, ("vfs_extd_audit: Debug class number of 'extd_audit': %d\n", vfs_extd_audit_debug_level));
}
-
+
return ret;
}
-/*
+/*
* Fake Perms VFS module. Implements passthrough operation of all VFS
* calls to disk functions, except for file permissions, which are now
* mode 0700 for the current uid/gid.
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
}
endmntent(f);
return;
-
+
nomem:
if (f) endmntent(f);
if (data->mount_entries[i].device == dev) {
return &data->mount_entries[i];
}
- }
+ }
return NULL;
}
-/*
+/*
* Auditing VFS module for samba. Log selected file operations to syslog
* facility.
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
* smbd_audit: nobody|192.168.234.1|open|fail (File not found)|r|x.txt
*
* where "nobody" is the connected username and "192.168.234.1" is the
- * client's IP address.
+ * client's IP address.
*
* Options:
*
static uint64_t smb_full_audit_disk_free(vfs_handle_struct *handle,
const char *path,
- bool small_query, uint64_t *bsize,
+ bool small_query, uint64_t *bsize,
uint64_t *dfree, uint64_t *dsize)
{
uint64_t result;
return result;
}
-
+
static int smb_full_audit_set_quota(struct vfs_handle_struct *handle,
enum SMB_QUOTA_TYPE qtype, unid_t id,
SMB_DISK_QUOTA *qt)
const char *path, mode_t mode)
{
int result;
-
+
result = SMB_VFS_NEXT_MKDIR(handle, path, mode);
-
+
do_log(SMB_VFS_OP_MKDIR, (result >= 0), handle, "%s", path);
return result;
const char *path)
{
int result;
-
+
result = SMB_VFS_NEXT_RMDIR(handle, path);
do_log(SMB_VFS_OP_RMDIR, (result >= 0), handle, "%s", path);
int result;
result = SMB_VFS_NEXT_CLOSEDIR(handle, dirp);
-
+
do_log(SMB_VFS_OP_CLOSEDIR, (result >= 0), handle, "");
return result;
files_struct *fsp, int flags, mode_t mode)
{
int result;
-
+
result = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode);
do_log(SMB_VFS_OP_OPEN, (result >= 0), handle, "%s|%s",
static int smb_full_audit_close(vfs_handle_struct *handle, files_struct *fsp)
{
int result;
-
+
result = SMB_VFS_NEXT_CLOSE(handle, fsp);
do_log(SMB_VFS_OP_CLOSE, (result >= 0), handle, "%s",
const struct smb_filename *smb_fname_dst)
{
int result;
-
+
result = SMB_VFS_NEXT_RENAME(handle, smb_fname_src, smb_fname_dst);
do_log(SMB_VFS_OP_RENAME, (result >= 0), handle, "%s|%s",
smb_fname_str_do_log(smb_fname_src),
smb_fname_str_do_log(smb_fname_dst));
- return result;
+ return result;
}
static int smb_full_audit_fsync(vfs_handle_struct *handle, files_struct *fsp)
{
int result;
-
+
result = SMB_VFS_NEXT_FSYNC(handle, fsp);
do_log(SMB_VFS_OP_FSYNC, (result >= 0), handle, "%s",
fsp_str_do_log(fsp));
- return result;
+ return result;
}
static int smb_full_audit_stat(vfs_handle_struct *handle,
struct smb_filename *smb_fname)
{
int result;
-
+
result = SMB_VFS_NEXT_STAT(handle, smb_fname);
do_log(SMB_VFS_OP_STAT, (result >= 0), handle, "%s",
smb_fname_str_do_log(smb_fname));
- return result;
+ return result;
}
static int smb_full_audit_fstat(vfs_handle_struct *handle, files_struct *fsp,
SMB_STRUCT_STAT *sbuf)
{
int result;
-
+
result = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
do_log(SMB_VFS_OP_FSTAT, (result >= 0), handle, "%s",
struct smb_filename *smb_fname)
{
int result;
-
+
result = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
do_log(SMB_VFS_OP_LSTAT, (result >= 0), handle, "%s",
smb_fname_str_do_log(smb_fname));
- return result;
+ return result;
}
static uint64_t smb_full_audit_get_alloc_size(vfs_handle_struct *handle,
const struct smb_filename *smb_fname)
{
int result;
-
+
result = SMB_VFS_NEXT_UNLINK(handle, smb_fname);
do_log(SMB_VFS_OP_UNLINK, (result >= 0), handle, "%s",
mode_t mode)
{
int result;
-
+
result = SMB_VFS_NEXT_FCHMOD(handle, fsp, mode);
do_log(SMB_VFS_OP_FCHMOD, (result >= 0), handle,
char *result;
result = SMB_VFS_NEXT_GETWD(handle, path);
-
+
do_log(SMB_VFS_OP_GETWD, (result != NULL), handle, "%s", path);
return result;
const char *path, mode_t mode)
{
int result;
-
+
result = SMB_VFS_NEXT_CHMOD_ACL(handle, path, mode);
do_log(SMB_VFS_OP_CHMOD_ACL, (result >= 0), handle,
mode_t mode)
{
int result;
-
+
result = SMB_VFS_NEXT_FCHMOD_ACL(handle, fsp, mode);
do_log(SMB_VFS_OP_FCHMOD_ACL, (result >= 0), handle,
{
NTSTATUS ret = smb_register_vfs(SMB_VFS_INTERFACE_VERSION,
"full_audit", &vfs_full_audit_fns);
-
+
if (!NT_STATUS_IS_OK(ret))
return ret;
DEBUG(10, ("vfs_full_audit: Debug class number of "
"'full_audit': %d\n", vfs_full_audit_debug_level));
}
-
+
return ret;
}
#include "nfs4_acls.h"
#include "vfs_gpfs.h"
-static int vfs_gpfs_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
+static int vfs_gpfs_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
uint32 share_mode, uint32 access_mask)
{
return SMB_VFS_NEXT_CLOSE(handle, fsp);
}
-static int vfs_gpfs_setlease(vfs_handle_struct *handle, files_struct *fsp,
+static int vfs_gpfs_setlease(vfs_handle_struct *handle, files_struct *fsp,
int leasetype)
{
int ret;
}
/* Tries to get nfs4 acls and returns SMB ACL allocated.
- * On failure returns 1 if it got non-NFSv4 ACL to prompt
+ * On failure returns 1 if it got non-NFSv4 ACL to prompt
* retry with POSIX ACL checks.
* On failure returns -1 if there is system (GPFS) error, check errno.
* Returns 0 on success
gace->aceWho == prev->aceWho) {
/* its redundent - skip it */
continue;
- }
+ }
}
smbace.aceType = gace->aceType;
ace->gid = (gid_t)g_ace->ace_who;
break;
case GPFS_ACL_GROUP_OBJ:
- ace->a_type = SMB_ACL_GROUP_OBJ;
+ ace->a_type = SMB_ACL_GROUP_OBJ;
break;
case GPFS_ACL_OTHER:
ace->a_type = SMB_ACL_OTHER;
if (errno != 0) {
SAFE_FREE(result);
}
- return result;
+ return result;
}
static SMB_ACL_T gpfsacl_sys_acl_get_file(vfs_handle_struct *handle,
/*
Unix SMB/CIFS implementation.
Wrap gpfs calls in vfs functions.
-
+
Copyright (C) Christian Ambach <cambach1@de.ibm.com> 2006
-
+
Major code contributions by Chetan Shringarpure <chetan.sh@in.ibm.com>
and Gomati Mohanan <gomati.mohanan@in.ibm.com>
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
+
*/
/*
* This module supports JFS (POSIX) ACLs on VxFS (Veritas * Filesystem).
- * These are available on HP-UX 11.00 if JFS 3.3 is installed.
+ * These are available on HP-UX 11.00 if JFS 3.3 is installed.
* On HP-UX 11i (11.11 and above) these ACLs are supported out of
* the box.
*
* and did similar adaptations as were done before, essentially
* reusing the original internal aclsort functions.
* The check for the presence of the acl() call has been adopted, and
- * a check for the presence of the aclsort() call has been added.
- *
+ * a check for the presence of the aclsort() call has been added.
+ *
* Michael Adam <obnox@samba.org>
*
* ================================================================= */
#include "includes.h"
-/*
- * including standard header <sys/aclv.h>
+/*
+ * including standard header <sys/aclv.h>
*
* included here as a quick hack for the special HP-UX-situation:
*
* The problem is that, on HP-UX, jfs/posix acls are
- * defined in <sys/aclv.h>, while the deprecated hfs acls
+ * defined in <sys/aclv.h>, while the deprecated hfs acls
* are defined inside <sys/acl.h>.
*
*/
typedef int HPUX_ACL_TAG_T; /* the type of an ACL entry */
typedef ushort HPUX_PERM_T;
-/* Structure to capture the count for each type of ACE.
+/* Structure to capture the count for each type of ACE.
* (for hpux_internal_aclsort */
struct hpux_acl_types {
int n_user;
/* prototypes for private functions */
static HPUX_ACL_T hpux_acl_init(int count);
-static bool smb_acl_to_hpux_acl(SMB_ACL_T smb_acl,
- HPUX_ACL_T *solariacl, int *count,
+static bool smb_acl_to_hpux_acl(SMB_ACL_T smb_acl,
+ HPUX_ACL_T *solariacl, int *count,
SMB_ACL_TYPE_T type);
static SMB_ACL_T hpux_acl_to_smb_acl(HPUX_ACL_T hpuxacl, int count,
SMB_ACL_TYPE_T type);
static SMB_ACL_TAG_T hpux_tag_to_smb_tag(HPUX_ACL_TAG_T hpux_tag);
static bool hpux_add_to_acl(HPUX_ACL_T *hpux_acl, int *count,
HPUX_ACL_T add_acl, int add_count, SMB_ACL_TYPE_T type);
-static bool hpux_acl_get_file(const char *name, HPUX_ACL_T *hpuxacl,
+static bool hpux_acl_get_file(const char *name, HPUX_ACL_T *hpuxacl,
int *count);
static SMB_ACL_PERM_T hpux_perm_to_smb_perm(const HPUX_PERM_T perm);
static HPUX_PERM_T smb_perm_to_hpux_perm(const SMB_ACL_PERM_T perm);
/* aclsort (internal) and helpers: */
static bool hpux_acl_sort(HPUX_ACL_T acl, int count);
static int hpux_internal_aclsort(int acl_count, int calclass, HPUX_ACL_T aclp);
-static void hpux_count_obj(int acl_count, HPUX_ACL_T aclp,
+static void hpux_count_obj(int acl_count, HPUX_ACL_T aclp,
struct hpux_acl_types *acl_type_count);
static void hpux_swap_acl_entries(HPUX_ACE_T *aclp0, HPUX_ACE_T *aclp1);
static bool hpux_prohibited_duplicate_type(int acl_type);
SMB_ACL_T result = NULL;
int count;
HPUX_ACL_T hpux_acl = NULL;
-
- DEBUG(10, ("hpuxacl_sys_acl_get_file called for file '%s'.\n",
+
+ DEBUG(10, ("hpuxacl_sys_acl_get_file called for file '%s'.\n",
path_p));
if(hpux_acl_call_present() == False) {
- /* Looks like we don't have the acl() system call on HPUX.
+ /* Looks like we don't have the acl() system call on HPUX.
* May be the system doesn't have the latest version of JFS.
*/
goto done;
goto done;
}
- DEBUGADD(10, ("getting %s acl\n",
+ DEBUGADD(10, ("getting %s acl\n",
((type == SMB_ACL_TYPE_ACCESS) ? "access" : "default")));
if (!hpux_acl_get_file(path_p, &hpux_acl, &count)) {
DEBUG(10, ("conversion hpux_acl -> smb_acl failed (%s).\n",
strerror(errno)));
}
-
+
done:
DEBUG(10, ("hpuxacl_sys_acl_get_file %s.\n",
((result == NULL) ? "failed" : "succeeded" )));
SMB_ACL_T hpuxacl_sys_acl_get_fd(vfs_handle_struct *handle,
files_struct *fsp)
{
- /*
- * HPUX doesn't have the facl call. Fake it using the path.... JRA.
+ /*
+ * HPUX doesn't have the facl call. Fake it using the path.... JRA.
*/
/* For all I see, the info should already be in the fsp
* parameter, but get it again to be safe --- necessary? */
int count;
struct smb_filename *smb_fname = NULL;
NTSTATUS status;
-
+
DEBUG(10, ("hpuxacl_sys_acl_set_file called for file '%s'\n",
name));
}
if(hpux_acl_call_present() == False) {
- /* Looks like we don't have the acl() system call on HPUX.
+ /* Looks like we don't have the acl() system call on HPUX.
* May be the system doesn't have the latest version of JFS.
*/
goto done;
DEBUG(10, ("invalid smb acl type given (%d).\n", type));
goto done;
}
- DEBUGADD(10, ("setting %s acl\n",
+ DEBUGADD(10, ("setting %s acl\n",
((type == SMB_ACL_TYPE_ACCESS) ? "access" : "default")));
if(!smb_acl_to_hpux_acl(theacl, &hpux_acl, &count, type)) {
/*
* if the file is a directory, there is extra work to do:
- * since the hpux acl call stores both the access acl and
- * the default acl as provided, we have to get the acl part
- * that has _not_ been specified in "type" from the file first
+ * since the hpux acl call stores both the access acl and
+ * the default acl as provided, we have to get the acl part
+ * that has _not_ been specified in "type" from the file first
* and concatenate it with the acl provided.
*/
if (lp_posix_pathnames()) {
goto done;
}
if (S_ISDIR(smb_fname->st.st_ex_mode)) {
- HPUX_ACL_T other_acl;
+ HPUX_ACL_T other_acl;
int other_count;
SMB_ACL_TYPE_T other_type;
- other_type = (type == SMB_ACL_TYPE_ACCESS)
+ other_type = (type == SMB_ACL_TYPE_ACCESS)
? SMB_ACL_TYPE_DEFAULT
: SMB_ACL_TYPE_ACCESS;
DEBUGADD(10, ("getting acl from filesystem\n"));
goto done;
}
DEBUG(10, ("adding %s part of fs acl to given acl\n",
- ((other_type == SMB_ACL_TYPE_ACCESS)
+ ((other_type == SMB_ACL_TYPE_ACCESS)
? "access"
: "default")));
if (!hpux_add_to_acl(&hpux_acl, &count, other_acl,
- other_count, other_type))
+ other_count, other_type))
{
DEBUG(10, ("error adding other acl.\n"));
SAFE_FREE(other_acl);
if (ret != 0) {
DEBUG(0, ("ERROR calling acl: %s\n", strerror(errno)));
}
-
+
done:
DEBUG(10, ("hpuxacl_sys_acl_set_file %s.\n",
((ret != 0) ? "failed" : "succeeded")));
}
/*
- * set the access ACL on the file referred to by a fd
+ * set the access ACL on the file referred to by a fd
*/
int hpuxacl_sys_acl_set_fd(vfs_handle_struct *handle,
files_struct *fsp,
/*
* delete the default ACL of a directory
*
- * This is achieved by fetching the access ACL and rewriting it
- * directly, via the hpux system call: the ACL_SET call on
+ * This is achieved by fetching the access ACL and rewriting it
+ * directly, via the hpux system call: the ACL_SET call on
* directories writes both the access and the default ACL as provided.
*
* XXX: posix acl_delete_def_file returns an error if
* the file referred to by path is not a directory.
- * this function does not complain but the actions
+ * this function does not complain but the actions
* have no effect on a file other than a directory.
* But sys_acl_delete_default_file is only called in
* smbd/posixacls.c after having checked that the file
int count;
DEBUG(10, ("entering hpuxacl_sys_acl_delete_def_file.\n"));
-
- smb_acl = hpuxacl_sys_acl_get_file(handle, path,
+
+ smb_acl = hpuxacl_sys_acl_get_file(handle, path,
SMB_ACL_TYPE_ACCESS);
if (smb_acl == NULL) {
DEBUG(10, ("getting file acl failed!\n"));
goto done;
}
- if (!smb_acl_to_hpux_acl(smb_acl, &hpux_acl, &count,
+ if (!smb_acl_to_hpux_acl(smb_acl, &hpux_acl, &count,
SMB_ACL_TYPE_ACCESS))
{
DEBUG(10, ("conversion smb_acl -> hpux_acl failed.\n"));
if (ret != 0) {
DEBUG(10, ("settinge file acl failed!\n"));
}
-
+
done:
DEBUG(10, ("hpuxacl_sys_acl_delete_def_file %s.\n",
((ret != 0) ? "failed" : "succeeded" )));
}
-/*
- * private functions
+/*
+ * private functions
*/
static HPUX_ACL_T hpux_acl_init(int count)
{
- HPUX_ACL_T hpux_acl =
+ HPUX_ACL_T hpux_acl =
(HPUX_ACL_T)SMB_MALLOC(sizeof(HPUX_ACE_T) * count);
if (hpux_acl == NULL) {
errno = ENOMEM;
}
/*
- * Convert the SMB acl to the ACCESS or DEFAULT part of a
+ * Convert the SMB acl to the ACCESS or DEFAULT part of a
* hpux ACL, as desired.
*/
-static bool smb_acl_to_hpux_acl(SMB_ACL_T smb_acl,
- HPUX_ACL_T *hpux_acl, int *count,
+static bool smb_acl_to_hpux_acl(SMB_ACL_T smb_acl,
+ HPUX_ACL_T *hpux_acl, int *count,
SMB_ACL_TYPE_T type)
{
bool ret = False;
int check_which, check_rc;
DEBUG(10, ("entering smb_acl_to_hpux_acl\n"));
-
+
*hpux_acl = NULL;
*count = 0;
}
switch(hpux_entry.a_type) {
case USER:
- DEBUG(10, ("got tag type USER with uid %d\n",
+ DEBUG(10, ("got tag type USER with uid %d\n",
smb_entry->uid));
hpux_entry.a_id = (uid_t)smb_entry->uid;
break;
case GROUP:
- DEBUG(10, ("got tag type GROUP with gid %d\n",
+ DEBUG(10, ("got tag type GROUP with gid %d\n",
smb_entry->gid));
hpux_entry.a_id = (uid_t)smb_entry->gid;
break;
DEBUG(10, ("adding default bit to hpux ace\n"));
hpux_entry.a_type |= ACL_DEFAULT;
}
-
- hpux_entry.a_perm =
+
+ hpux_entry.a_perm =
smb_perm_to_hpux_perm(smb_entry->a_perm);
DEBUG(10, ("assembled the following hpux ace:\n"));
DEBUGADD(10, (" - type: 0x%04x\n", hpux_entry.a_type));
DEBUGADD(10, (" - id: %d\n", hpux_entry.a_id));
DEBUGADD(10, (" - perm: o%o\n", hpux_entry.a_perm));
- if (!hpux_add_to_acl(hpux_acl, count, &hpux_entry,
+ if (!hpux_add_to_acl(hpux_acl, count, &hpux_entry,
1, type))
{
DEBUG(10, ("error adding acl entry\n"));
ret = True;
goto done;
-
+
fail:
SAFE_FREE(*hpux_acl);
done:
return ret;
}
-/*
- * convert either the access or the default part of a
+/*
+ * convert either the access or the default part of a
* soaris acl to the SMB_ACL format.
*/
-static SMB_ACL_T hpux_acl_to_smb_acl(HPUX_ACL_T hpux_acl, int count,
+static SMB_ACL_T hpux_acl_to_smb_acl(HPUX_ACL_T hpux_acl, int count,
SMB_ACL_TYPE_T type)
{
SMB_ACL_T result;
for (i = 0; i < count; i++) {
SMB_ACL_ENTRY_T smb_entry;
SMB_ACL_PERM_T smb_perm;
-
+
if (!_IS_OF_TYPE(hpux_acl[i], type)) {
continue;
}
- result = SMB_REALLOC(result,
+ result = SMB_REALLOC(result,
sizeof(struct smb_acl_t) +
(sizeof(struct smb_acl_entry) *
(result->count + 1)));
sys_acl_set_qualifier(smb_entry, (void *)&hpux_acl[i].a_id);
smb_perm = hpux_perm_to_smb_perm(hpux_acl[i].a_perm);
if (sys_acl_set_permset(smb_entry, &smb_perm) != 0) {
- DEBUG(10, ("invalid permset given: %d\n",
+ DEBUG(10, ("invalid permset given: %d\n",
hpux_acl[i].a_perm));
goto fail;
}
result->count += 1;
}
goto done;
-
+
fail:
SAFE_FREE(result);
done:
DEBUG(10, ("smb_tag_to_hpux_tag\n"));
DEBUGADD(10, (" --> got smb tag 0x%04x\n", smb_tag));
-
+
switch (smb_tag) {
case SMB_ACL_USER:
hpux_tag = USER;
DEBUGADD(10, (" !!! unknown smb tag type 0x%04x\n", smb_tag));
break;
}
-
+
DEBUGADD(10, (" --> determined hpux tag 0x%04x\n", hpux_tag));
return hpux_tag;
SMB_ACL_TAG_T smb_tag = 0;
DEBUG(10, ("hpux_tag_to_smb_tag:\n"));
- DEBUGADD(10, (" --> got hpux tag 0x%04x\n", hpux_tag));
-
- hpux_tag &= ~ACL_DEFAULT;
+ DEBUGADD(10, (" --> got hpux tag 0x%04x\n", hpux_tag));
+
+ hpux_tag &= ~ACL_DEFAULT;
switch (hpux_tag) {
case USER:
smb_tag = SMB_ACL_MASK;
break;
default:
- DEBUGADD(10, (" !!! unknown hpux tag type: 0x%04x\n",
+ DEBUGADD(10, (" !!! unknown hpux tag type: 0x%04x\n",
hpux_tag));
break;
}
DEBUGADD(10, (" --> determined smb tag 0x%04x\n", smb_tag));
-
+
return smb_tag;
}
-/*
- * The permission bits used in the following two permission conversion
- * functions are same, but the functions make us independent of the concrete
+/*
+ * The permission bits used in the following two permission conversion
+ * functions are same, but the functions make us independent of the concrete
* permission data types.
*/
static SMB_ACL_PERM_T hpux_perm_to_smb_perm(const HPUX_PERM_T perm)
}
-static bool hpux_acl_get_file(const char *name, HPUX_ACL_T *hpux_acl,
+static bool hpux_acl_get_file(const char *name, HPUX_ACL_T *hpux_acl,
int *count)
{
bool result = False;
static HPUX_ACE_T dummy_ace;
DEBUG(10, ("hpux_acl_get_file called for file '%s'\n", name));
-
- /*
+
+ /*
* The original code tries some INITIAL_ACL_SIZE
* and only did the ACL_CNT call upon failure
* (for performance reasons).
- * For the sake of simplicity, I skip this for now.
+ * For the sake of simplicity, I skip this for now.
*
* NOTE: There is a catch here on HP-UX: acl with cmd parameter
* ACL_CNT fails with errno EINVAL when called with a NULL
* Add entries to a hpux ACL.
*
* Entries are directly added to the hpuxacl parameter.
- * if memory allocation fails, this may result in hpuxacl
- * being NULL. if the resulting acl is to be checked and is
+ * if memory allocation fails, this may result in hpuxacl
+ * being NULL. if the resulting acl is to be checked and is
* not valid, it is kept in hpuxacl but False is returned.
*
- * The type of ACEs (access/default) to be added to the ACL can
- * be selected via the type parameter.
+ * The type of ACEs (access/default) to be added to the ACL can
+ * be selected via the type parameter.
* I use the SMB_ACL_TYPE_T type here. Since SMB_ACL_TYPE_ACCESS
* is defined as "0", this means that one can only add either
- * access or default ACEs from the given ACL, not both at the same
- * time. If it should become necessary to add all of an ACL, one
+ * access or default ACEs from the given ACL, not both at the same
+ * time. If it should become necessary to add all of an ACL, one
* would have to replace this parameter by another type.
*/
static bool hpux_add_to_acl(HPUX_ACL_T *hpux_acl, int *count,
- HPUX_ACL_T add_acl, int add_count,
+ HPUX_ACL_T add_acl, int add_count,
SMB_ACL_TYPE_T type)
{
int i;
-
- if ((type != SMB_ACL_TYPE_ACCESS) && (type != SMB_ACL_TYPE_DEFAULT))
+
+ if ((type != SMB_ACL_TYPE_ACCESS) && (type != SMB_ACL_TYPE_DEFAULT))
{
DEBUG(10, ("invalid acl type given: %d\n", type));
errno = EINVAL;
if (!_IS_OF_TYPE(add_acl[i], type)) {
continue;
}
- ADD_TO_ARRAY(NULL, HPUX_ACE_T, add_acl[i],
+ ADD_TO_ARRAY(NULL, HPUX_ACE_T, add_acl[i],
hpux_acl, count);
if (hpux_acl == NULL) {
DEBUG(10, ("error enlarging acl.\n"));
}
-/*
+/*
* sort the ACL and check it for validity
*
* [original comment from lib/sysacls.c:]
- *
+ *
* if it's a minimal ACL with only 4 entries then we
* need to recalculate the mask permissions to make
* sure that they are the same as the GROUP_OBJ
* aclp - Array of ACL structures.
* acl_type_count - Pointer to acl_types structure. Should already be
* allocated.
- * Output:
+ * Output:
*
- * acl_type_count - This structure is filled up with counts of various
+ * acl_type_count - This structure is filled up with counts of various
* acl types.
*/
for(i=0;i<acl_count;i++) {
switch(aclp[i].a_type) {
- case USER:
+ case USER:
acl_type_count->n_user++;
break;
- case USER_OBJ:
+ case USER_OBJ:
acl_type_count->n_user_obj++;
break;
- case DEF_USER_OBJ:
+ case DEF_USER_OBJ:
acl_type_count->n_def_user_obj++;
break;
- case GROUP:
+ case GROUP:
acl_type_count->n_group++;
break;
- case GROUP_OBJ:
+ case GROUP_OBJ:
acl_type_count->n_group_obj++;
break;
- case DEF_GROUP_OBJ:
+ case DEF_GROUP_OBJ:
acl_type_count->n_def_group_obj++;
break;
- case OTHER_OBJ:
+ case OTHER_OBJ:
acl_type_count->n_other_obj++;
break;
- case DEF_OTHER_OBJ:
+ case DEF_OTHER_OBJ:
acl_type_count->n_def_other_obj++;
break;
case CLASS_OBJ:
case DEF_GROUP:
acl_type_count->n_def_group++;
break;
- default:
+ default:
acl_type_count->n_illegal_obj++;
break;
}
}
}
-/* hpux_swap_acl_entries: Swaps two ACL entries.
+/* hpux_swap_acl_entries: Swaps two ACL entries.
*
* Inputs: aclp0, aclp1 - ACL entries to be swapped.
*/
}
/* hpux_prohibited_duplicate_type
- * Identifies if given ACL type can have duplicate entries or
+ * Identifies if given ACL type can have duplicate entries or
* not.
*
* Inputs: acl_type - ACL Type.
*
- * Outputs:
+ * Outputs:
*
- * Return..
+ * Return..
*
* True - If the ACL type matches any of the prohibited types.
* False - If the ACL type doesn't match any of the prohibited types.
- */
+ */
static bool hpux_prohibited_duplicate_type(int acl_type)
{
switch(acl_type) {
case USER:
case GROUP:
- case DEF_USER:
+ case DEF_USER:
case DEF_GROUP:
return True;
default:
/* hpux_get_needed_class_perm
* Returns the permissions of a ACL structure only if the ACL
- * type matches one of the pre-determined types for computing
+ * type matches one of the pre-determined types for computing
* CLASS_OBJ permissions.
*
* Inputs: aclp - Pointer to ACL structure.
static int hpux_get_needed_class_perm(struct acl *aclp)
{
switch(aclp->a_type) {
- case USER:
- case GROUP_OBJ:
- case GROUP:
- case DEF_USER_OBJ:
+ case USER:
+ case GROUP_OBJ:
+ case GROUP:
+ case DEF_USER_OBJ:
case DEF_USER:
- case DEF_GROUP_OBJ:
+ case DEF_GROUP_OBJ:
case DEF_GROUP:
case DEF_CLASS_OBJ:
- case DEF_OTHER_OBJ:
+ case DEF_OTHER_OBJ:
return aclp->a_perm;
- default:
+ default:
return 0;
}
}
/* hpux_internal_aclsort: aclsort for HPUX.
*
* -> The aclsort() system call is availabe on the latest HPUX General
- * -> Patch Bundles. So for HPUX, we developed our version of aclsort
- * -> function. Because, we don't want to update to a new
+ * -> Patch Bundles. So for HPUX, we developed our version of aclsort
+ * -> function. Because, we don't want to update to a new
* -> HPUX GR bundle just for aclsort() call.
*
* aclsort sorts the array of ACL structures as per the description in
struct hpux_acl_types acl_obj_count;
int n_class_obj_perm = 0;
int i, j;
-
+
DEBUG(10,("Entering hpux_internal_aclsort. (calclass = %d)\n", calclass));
if (hpux_aclsort_call_present()) {
hpux_count_obj(acl_count, aclp, &acl_obj_count);
- /* There should be only one entry each of type USER_OBJ, GROUP_OBJ,
- * CLASS_OBJ and OTHER_OBJ
+ /* There should be only one entry each of type USER_OBJ, GROUP_OBJ,
+ * CLASS_OBJ and OTHER_OBJ
*/
- if ( (acl_obj_count.n_user_obj != 1) ||
- (acl_obj_count.n_group_obj != 1) ||
+ if ( (acl_obj_count.n_user_obj != 1) ||
+ (acl_obj_count.n_group_obj != 1) ||
(acl_obj_count.n_class_obj != 1) ||
- (acl_obj_count.n_other_obj != 1) )
+ (acl_obj_count.n_other_obj != 1) )
{
DEBUG(0,("hpux_internal_aclsort: More than one entry or no entries for \
USER OBJ or GROUP_OBJ or OTHER_OBJ or CLASS_OBJ\n"));
* one of them each.
*/
- if ( (acl_obj_count.n_def_user_obj > 1) ||
- (acl_obj_count.n_def_group_obj > 1) ||
- (acl_obj_count.n_def_other_obj > 1) ||
- (acl_obj_count.n_def_class_obj > 1) )
+ if ( (acl_obj_count.n_def_user_obj > 1) ||
+ (acl_obj_count.n_def_group_obj > 1) ||
+ (acl_obj_count.n_def_other_obj > 1) ||
+ (acl_obj_count.n_def_class_obj > 1) )
{
DEBUG(0,("hpux_internal_aclsort: More than one entry for DEF_CLASS_OBJ \
or DEF_USER_OBJ or DEF_GROUP_OBJ or DEF_OTHER_OBJ\n"));
return -1;
}
- /* We now have proper number of OBJ and DEF_OBJ entries. Now sort the acl
- * structures.
+ /* We now have proper number of OBJ and DEF_OBJ entries. Now sort the acl
+ * structures.
*
* Sorting crieteria - First sort by ACL type. If there are multiple entries of
* same ACL type, sort by ACL id.
*
- * I am using the trival kind of sorting method here because, performance isn't
+ * I am using the trival kind of sorting method here because, performance isn't
* really effected by the ACLs feature. More over there aren't going to be more
- * than 17 entries on HPUX.
+ * than 17 entries on HPUX.
*/
for(i=0; i<acl_count;i++) {
}
-/*
+/*
* hpux_acl_call_present:
*
* This checks if the POSIX ACL system call is defined
* higher is installed. If acl() was called when it
* isn't defined, it causes the process to core dump
* so it is important to check this and avoid acl()
- * calls if it isn't there.
+ * calls if it isn't there.
*/
static bool hpux_acl_call_present(void)
return True;
}
-/*
- * runtime check for presence of aclsort library call.
+/*
+ * runtime check for presence of aclsort library call.
* same code as for acl call. if there are more of these,
* a dispatcher function could be handy...
*/
-static bool hpux_aclsort_call_present(void)
+static bool hpux_aclsort_call_present(void)
{
shl_t handle = NULL;
void *value;
ret_val = shl_findsym(&handle, "aclsort", TYPE_PROCEDURE, &value);
if (ret_val != 0) {
DEBUG(5, ("hpux_aclsort_call_present: shl_findsym "
- "returned %d, errno = %d, error %s",
+ "returned %d, errno = %d, error %s",
ret_val, errno, strerror(errno)));
DEBUG(5, ("hpux_aclsort_call_present: "
"aclsort() function not available.\n"));
{
int check_rc;
int check_which;
-
+
check_rc = aclcheck(hpux_acl, count, &check_which);
if (check_rc != 0) {
DEBUG(10, ("acl is not valid:\n"));
DEBUGADD(10, (" - which: %d\n", check_which));
if (check_which != -1) {
DEBUGADD(10, (" - invalid entry:\n"));
- DEBUGADD(10, (" * type: %d:\n",
+ DEBUGADD(10, (" * type: %d:\n",
hpux_acl[check_which].a_type));
DEBUGADD(10, (" * id: %d\n",
hpux_acl[check_which].a_id));
NTSTATUS vfs_hpuxacl_init(void);
#endif
-
NTSTATUS vfs_irixacl_init(void);
#endif
-
-/*
+/*
* AppleTalk VFS module for Samba-3.x
*
* Copyright (C) Alexei Kotovich, 2002
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
{
int i = 0;
int ptr = 0;
-
+
for (i = 0; path[i]; i ++) {
if (path[i] == '/')
ptr = i;
break;
}
}
-
+
return ptr;
}
sys_lstat(*orig_path, orig_info, fake_dir_create_times);
if (S_ISDIR(orig_info->st_ex_mode)) {
- *adbl_path = talloc_asprintf(ctx, "%s/%s/%s/",
+ *adbl_path = talloc_asprintf(ctx, "%s/%s/%s/",
path, &fname[ptr0], APPLEDOUBLE);
} else {
dname = talloc_strdup(ctx, *orig_path);
dname[ptr1] = '\0';
name = *orig_path;
- *adbl_path = talloc_asprintf(ctx, "%s/%s/%s",
+ *adbl_path = talloc_asprintf(ctx, "%s/%s/%s",
dname, APPLEDOUBLE, &name[ptr1 + 1]);
}
#if 0
- DEBUG(3, ("ATALK: DEBUG:\n%s\n%s\n", *orig_path, *adbl_path));
+ DEBUG(3, ("ATALK: DEBUG:\n%s\n%s\n", *orig_path, *adbl_path));
#endif
sys_lstat(*adbl_path, adbl_info, fake_dir_create_times);
return 0;
become_root();
ret = unlink(path);
unbecome_root();
-
+
return ret;
}
if (strcmp(dent->d_name, ".") == 0 ||
strcmp(dent->d_name, "..") == 0)
continue;
- if (!(dpath = talloc_asprintf(ctx, "%s/%s",
+ if (!(dpath = talloc_asprintf(ctx, "%s/%s",
path, dent->d_name)))
continue;
atalk_unlink_file(dpath);
* in ./.AppleDouble and this directory wasn't hidden by Samba,
* MS Windows explorer causes the error: "Cannot find the specified file"
* There is some workaround to avoid this situation, i.e. if
- * connection has not .AppleDouble entry in either veto or hide
+ * connection has not .AppleDouble entry in either veto or hide
* list then it would be nice to add one.
*/
if (!(ctx = talloc_init("remove_directory")))
goto exit_rmdir;
- if (!(dpath = talloc_asprintf(ctx, "%s/%s%s",
+ if (!(dpath = talloc_asprintf(ctx, "%s/%s%s",
handle->conn->origpath, path, add ? "/"APPLEDOUBLE : "")))
goto exit_rmdir;
goto exit_rename;
if (S_ISDIR(orig_info.st_ex_mode) || S_ISREG(orig_info.st_ex_mode)) {
- DEBUG(3, ("ATALK: %s has passed..\n", adbl_path));
+ DEBUG(3, ("ATALK: %s has passed..\n", adbl_path));
goto exit_rename;
}
break;
else {
DEBUG(3, ("ATALK: %s is not hidden, skipped..\n",
- APPLEDOUBLE));
+ APPLEDOUBLE));
goto exit_unlink;
}
}
goto exit_chmod;
if (!S_ISDIR(orig_info.st_ex_mode) && !S_ISREG(orig_info.st_ex_mode)) {
- DEBUG(3, ("ATALK: %s has passed..\n", orig_path));
+ DEBUG(3, ("ATALK: %s has passed..\n", orig_path));
goto exit_chmod;
}
chmod(adbl_path, ADOUBLEMODE);
-exit_chmod:
+exit_chmod:
talloc_destroy(ctx);
return ret;
}
goto exit_chown;
if (!S_ISDIR(orig_info.st_ex_mode) && !S_ISREG(orig_info.st_ex_mode)) {
- DEBUG(3, ("ATALK: %s has passed..\n", orig_path));
+ DEBUG(3, ("ATALK: %s has passed..\n", orig_path));
goto exit_chown;
}
DEBUG(3, ("ATALK: chown error %s\n", strerror(errno)));
}
-exit_chown:
+exit_chown:
talloc_destroy(ctx);
return ret;
}
goto exit_lchown;
if (!S_ISDIR(orig_info.st_ex_mode) && !S_ISREG(orig_info.st_ex_mode)) {
- DEBUG(3, ("ATALK: %s has passed..\n", orig_path));
+ DEBUG(3, ("ATALK: %s has passed..\n", orig_path));
goto exit_lchown;
}
DEBUG(3, ("ATALK: lchown error %s\n", strerror(errno)));
}
-exit_lchown:
+exit_lchown:
talloc_destroy(ctx);
return ret;
}
FAMConnection *fam_connection;
struct FAMRequest fr;
struct sys_notify_context *sys_ctx;
- void (*callback)(struct sys_notify_context *ctx,
+ void (*callback)(struct sys_notify_context *ctx,
void *private_data,
struct notify_event *ev);
void *private_data;
static NTSTATUS fam_watch(vfs_handle_struct *vfs_handle,
struct sys_notify_context *ctx,
struct notify_entry *e,
- void (*callback)(struct sys_notify_context *ctx,
+ void (*callback)(struct sys_notify_context *ctx,
void *private_data,
struct notify_event *ev),
- void *private_data,
+ void *private_data,
void *handle_p)
{
const uint32 fam_mask = (FILE_NOTIFY_CHANGE_FILE_NAME|
acl_free(puid);
break;
}
-
+
case SMB_ACL_GROUP: {
gid_t *pgid = (uid_t *)acl_get_qualifier(posix_ace);
if (pgid == NULL) {
NTSTATUS vfs_posixacl_init(void);
#endif
-
bool didmsg;
};
-/*
+/*
* This module copes with Vista AIO read requests on Linux
* by detecting the initial 0x80000 boundary reads and causing
* the buffer cache to be filled in advance.
#include "getdate.h"
/*
- This module performs a read-only limitation for specified share
+ This module performs a read-only limitation for specified share
(or all of them if it is loaded in a [global] section) based on period
- definition in smb.conf. You can stack this module multiple times under
+ definition in smb.conf. You can stack this module multiple times under
different names to get multiple limit intervals.
The module uses get_date() function from coreutils' date utility to parse
specified dates according to date(1) rules. Look into info page for date(1)
to understand the syntax.
- The module accepts one parameter:
+ The module accepts one parameter:
readonly: period = "begin date","end date"
- where "begin date" and "end date" are mandatory and should comply with date(1)
+ where "begin date" and "end date" are mandatory and should comply with date(1)
syntax for date strings.
Example:
*/
#define MODULE_NAME "readonly"
-static int readonly_connect(vfs_handle_struct *handle,
- const char *service,
- const char *user)
+static int readonly_connect(vfs_handle_struct *handle,
+ const char *service,
+ const char *user)
{
const char *period_def[] = {"today 0:0:0", "tomorrow 0:0:0"};
const char **period = lp_parm_string_list(SNUM(handle->conn),
(handle->param ? handle->param : MODULE_NAME),
- "period", period_def);
+ "period", period_def);
int ret = SMB_VFS_NEXT_CONNECT(handle, service, user);
if (ret < 0) {
return 0;
} else {
-
+
return 0;
-
+
}
}
#undef DBGC_CLASS
#define DBGC_CLASS vfs_recycle_debug_level
-
+
static int recycle_connect(vfs_handle_struct *handle, const char *service, const char *user);
static void recycle_disconnect(vfs_handle_struct *handle);
static int recycle_unlink(vfs_handle_struct *handle,
return False;
}
- /*
+ /*
* Walk the components of path, looking for matches with the
- * exclude list on each component.
+ * exclude list on each component.
*/
for (startp = path; startp; startp = endp) {
{
connection_struct *conn = handle->conn;
char *path_name = NULL;
- char *temp_name = NULL;
+ char *temp_name = NULL;
char *final_name = NULL;
struct smb_filename *smb_fname_final = NULL;
const char *base;
-/*
+/*
* implementation of an Shadow Copy module
*
* Copyright (C) Stefan Metzmacher 2003-2004
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
Z:\@GMT-2003.08.05-12.02.00\
e.g.
-
+
Z:\testfile.txt
Z:\@GMT-2003.08.05-12.02.00\testfile.txt
Note: Files must differ to be displayed via Windows Explorer!
- Directories are always displayed...
+ Directories are always displayed...
*/
static int vfs_shadow_copy_debug_level = DBGC_VFS;
SAFE_FREE(dirp->dirs);
SAFE_FREE(dirp);
-
- return 0;
+
+ return 0;
}
static int shadow_copy_get_shadow_copy_data(vfs_handle_struct *handle, files_struct *fsp, SHADOW_COPY_DATA *shadow_copy_data, bool labels)
DEBUG(0, ("%s: Couldn't register custom debugging class!\n",
"vfs_shadow_copy_init"));
} else {
- DEBUG(10, ("%s: Debug class number of '%s': %d\n",
+ DEBUG(10, ("%s: Debug class number of '%s': %d\n",
"vfs_shadow_copy_init","shadow_copy",vfs_shadow_copy_debug_level));
}
-/*
+/*
* implementation of an Shadow Copy module - version 2
*
* Copyright (C) Andrew Tridgell 2007
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
The following command would generate a correctly formatted directory name
for use with the default parameters:
date -u +@GMT-%Y.%m.%d-%H.%M.%S
-
+
*/
static int vfs_shadow_copy2_debug_level = DBGC_VFS;
#define SHADOW_COPY2_DEFAULT_LOCALTIME false
/*
- make very sure it is one of our special names
+ make very sure it is one of our special names
*/
static inline bool shadow_copy2_match_name(const char *name, const char **gmt_start)
{
}
}
- return path;
+ return path;
}
/*
if (*baseoffset == '/') baseoffset++;
ret = talloc_asprintf(handle->data, "%s/%s/%s/%s",
- snapdir,
+ snapdir,
snapshot,
- baseoffset,
+ baseoffset,
relpath);
DEBUG(6,("convert_shadow2_name: '%s' -> '%s'\n", fname, ret));
talloc_free(tmp_ctx);
*/
static void convert_sbuf(vfs_handle_struct *handle, const char *fname, SMB_STRUCT_STAT *sbuf)
{
- if (lp_parm_bool(SNUM(handle->conn), "shadow", "fixinodes", False)) {
+ if (lp_parm_bool(SNUM(handle->conn), "shadow", "fixinodes", False)) {
/* some snapshot systems, like GPFS, return the name
device:inode for the snapshot files as the current
files. That breaks the 'restore' button in the shadow copy
SHADOW2_NEXT(LGETXATTR, (handle, name, aname, value, size), ssize_t, -1);
}
-static ssize_t shadow_copy2_listxattr(struct vfs_handle_struct *handle, const char *fname,
+static ssize_t shadow_copy2_listxattr(struct vfs_handle_struct *handle, const char *fname,
char *list, size_t size)
{
SHADOW2_NEXT(LISTXATTR, (handle, name, list, size), ssize_t, -1);
}
-static int shadow_copy2_removexattr(struct vfs_handle_struct *handle, const char *fname,
+static int shadow_copy2_removexattr(struct vfs_handle_struct *handle, const char *fname,
const char *aname)
{
SHADOW2_NEXT(REMOVEXATTR, (handle, name, aname), int, -1);
}
-static int shadow_copy2_lremovexattr(struct vfs_handle_struct *handle, const char *fname,
+static int shadow_copy2_lremovexattr(struct vfs_handle_struct *handle, const char *fname,
const char *aname)
{
SHADOW2_NEXT(LREMOVEXATTR, (handle, name, aname), int, -1);
}
-static int shadow_copy2_setxattr(struct vfs_handle_struct *handle, const char *fname,
+static int shadow_copy2_setxattr(struct vfs_handle_struct *handle, const char *fname,
const char *aname, const void *value, size_t size, int flags)
{
SHADOW2_NEXT(SETXATTR, (handle, name, aname, value, size, flags), int, -1);
}
-static int shadow_copy2_lsetxattr(struct vfs_handle_struct *handle, const char *fname,
+static int shadow_copy2_lsetxattr(struct vfs_handle_struct *handle, const char *fname,
const char *aname, const void *value, size_t size, int flags)
{
SHADOW2_NEXT(LSETXATTR, (handle, name, aname, value, size, flags), int, -1);
return;
}
-static int shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle,
- files_struct *fsp,
- SHADOW_COPY_DATA *shadow_copy2_data,
+static int shadow_copy2_get_shadow_copy2_data(vfs_handle_struct *handle,
+ files_struct *fsp,
+ SHADOW_COPY_DATA *shadow_copy2_data,
bool labels)
{
SMB_STRUCT_DIR *p;
DEBUG(0, ("%s: Couldn't register custom debugging class!\n",
"vfs_shadow_copy2_init"));
} else {
- DEBUG(10, ("%s: Debug class number of '%s': %d\n",
+ DEBUG(10, ("%s: Debug class number of '%s': %d\n",
"vfs_shadow_copy2_init","shadow_copy2",vfs_shadow_copy2_debug_level));
}
samba_AES_encrypt( (unsigned char *) str+(16*h), filler, &key );
for (d = 0;d < 16; d++) output[d+(16*h)]=*(filler+d);
*len = (s1*16)+16;
- return output;
+ return output;
}
/**
struct tm *tm, int seconds, vfs_handle_struct *handle, \
char *username, int vfs_operation, int count, ... )
{
-
+
va_list ap;
char *arg = NULL;
int len;
common_data_count_str,
usersid,
handle);
-
+
/* time stamp */
timestr = talloc_asprintf( common_data_count_str, \
"%04d-%02d-%02d %02d:%02d:%02d.%03d", \
talloc_free(common_data_count_str);
- /* data blocks depending on the VFS function */
+ /* data blocks depending on the VFS function */
va_start( ap, count );
while ( count-- ) {
arg = va_arg( ap, char * );
tm->tm_sec,
(int)seconds);
if (write_data(rf_sock->sock, str, len) != len) {
- DEBUG(1, ("smb_traffic_analyzer_send_data_socket: "
+ DEBUG(1, ("smb_traffic_analyzer_send_data_socket: "
"error sending V1 protocol data to socket!\n"));
return;
}
}
/* If we're connected already, just increase the
- * reference count. */
+ * reference count. */
if (rf_sock) {
rf_sock->ref_count++;
} else {
return s_data.result;
}
-
+
static struct vfs_fn_pointers vfs_smb_traffic_analyzer_fns = {
.connect_fn = smb_traffic_analyzer_connect,
.vfs_read = smb_traffic_analyzer_read,
char *filename;
size_t len;
};
-
-
/* prototypes for private functions */
static SOLARIS_ACL_T solaris_acl_init(int count);
-static bool smb_acl_to_solaris_acl(SMB_ACL_T smb_acl,
- SOLARIS_ACL_T *solariacl, int *count,
+static bool smb_acl_to_solaris_acl(SMB_ACL_T smb_acl,
+ SOLARIS_ACL_T *solariacl, int *count,
SMB_ACL_TYPE_T type);
static SMB_ACL_T solaris_acl_to_smb_acl(SOLARIS_ACL_T solarisacl, int count,
SMB_ACL_TYPE_T type);
static SMB_ACL_TAG_T solaris_tag_to_smb_tag(SOLARIS_ACL_TAG_T solaris_tag);
static bool solaris_add_to_acl(SOLARIS_ACL_T *solaris_acl, int *count,
SOLARIS_ACL_T add_acl, int add_count, SMB_ACL_TYPE_T type);
-static bool solaris_acl_get_file(const char *name, SOLARIS_ACL_T *solarisacl,
+static bool solaris_acl_get_file(const char *name, SOLARIS_ACL_T *solarisacl,
int *count);
static bool solaris_acl_get_fd(int fd, SOLARIS_ACL_T *solarisacl, int *count);
static bool solaris_acl_sort(SOLARIS_ACL_T theacl, int count);
SMB_ACL_T result = NULL;
int count;
SOLARIS_ACL_T solaris_acl = NULL;
-
- DEBUG(10, ("solarisacl_sys_acl_get_file called for file '%s'.\n",
+
+ DEBUG(10, ("solarisacl_sys_acl_get_file called for file '%s'.\n",
path_p));
if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) {
goto done;
}
- DEBUGADD(10, ("getting %s acl\n",
+ DEBUGADD(10, ("getting %s acl\n",
((type == SMB_ACL_TYPE_ACCESS) ? "access" : "default")));
if (!solaris_acl_get_file(path_p, &solaris_acl, &count)) {
DEBUG(10, ("conversion solaris_acl -> smb_acl failed (%s).\n",
strerror(errno)));
}
-
+
done:
DEBUG(10, ("solarisacl_sys_acl_get_file %s.\n",
((result == NULL) ? "failed" : "succeeded" )));
if (!solaris_acl_get_fd(fsp->fh->fd, &solaris_acl, &count)) {
goto done;
}
- /*
- * The facl call returns both ACCESS and DEFAULT acls (as present).
+ /*
+ * The facl call returns both ACCESS and DEFAULT acls (as present).
* The posix acl_get_fd function returns only the
- * access acl. So we need to filter this out here.
+ * access acl. So we need to filter this out here.
*/
result = solaris_acl_to_smb_acl(solaris_acl, count,
SMB_ACL_TYPE_ACCESS);
DEBUG(10, ("conversion solaris_acl -> smb_acl failed (%s).\n",
strerror(errno)));
}
-
+
done:
- DEBUG(10, ("solarisacl_sys_acl_get_fd %s.\n",
+ DEBUG(10, ("solarisacl_sys_acl_get_fd %s.\n",
((result == NULL) ? "failed" : "succeeded")));
SAFE_FREE(solaris_acl);
return result;
struct stat_ex s;
SOLARIS_ACL_T solaris_acl = NULL;
int count;
-
+
DEBUG(10, ("solarisacl_sys_acl_set_file called for file '%s'\n",
name));
DEBUG(10, ("invalid smb acl type given (%d).\n", type));
goto done;
}
- DEBUGADD(10, ("setting %s acl\n",
+ DEBUGADD(10, ("setting %s acl\n",
((type == SMB_ACL_TYPE_ACCESS) ? "access" : "default")));
if(!smb_acl_to_solaris_acl(theacl, &solaris_acl, &count, type)) {
/*
* if the file is a directory, there is extra work to do:
- * since the solaris acl call stores both the access acl and
- * the default acl as provided, we have to get the acl part
- * that has not been specified in "type" from the file first
+ * since the solaris acl call stores both the access acl and
+ * the default acl as provided, we have to get the acl part
+ * that has not been specified in "type" from the file first
* and concatenate it with the acl provided.
*/
if (vfs_stat_smb_fname(handle->conn, name, &s) != 0) {
goto done;
}
if (S_ISDIR(s.st_ex_mode)) {
- SOLARIS_ACL_T other_acl;
+ SOLARIS_ACL_T other_acl;
int other_count;
SMB_ACL_TYPE_T other_type;
- other_type = (type == SMB_ACL_TYPE_ACCESS)
+ other_type = (type == SMB_ACL_TYPE_ACCESS)
? SMB_ACL_TYPE_DEFAULT
: SMB_ACL_TYPE_ACCESS;
DEBUGADD(10, ("getting acl from filesystem\n"));
goto done;
}
DEBUG(10, ("adding %s part of fs acl to given acl\n",
- ((other_type == SMB_ACL_TYPE_ACCESS)
+ ((other_type == SMB_ACL_TYPE_ACCESS)
? "access"
: "default")));
if (!solaris_add_to_acl(&solaris_acl, &count, other_acl,
- other_count, other_type))
+ other_count, other_type))
{
DEBUG(10, ("error adding other acl.\n"));
SAFE_FREE(other_acl);
}
ret = acl(name, SETACL, count, solaris_acl);
-
+
done:
DEBUG(10, ("solarisacl_sys_acl_set_file %s.\n",
((ret != 0) ? "failed" : "succeeded")));
}
/*
- * set the access ACL on the file referred to by a fd
+ * set the access ACL on the file referred to by a fd
*/
int solarisacl_sys_acl_set_fd(vfs_handle_struct *handle,
files_struct *fsp,
DEBUG(10, ("entering solarisacl_sys_acl_set_fd\n"));
- /*
+ /*
* the posix acl_set_fd call sets the access acl of the
* file referred to by fd. the solaris facl-SETACL call
* sets the access and default acl as provided, so we
- * have to retrieve the default acl of the file and
+ * have to retrieve the default acl of the file and
* concatenate it with the access acl provided.
*/
- if (!smb_acl_to_solaris_acl(theacl, &solaris_acl, &count,
+ if (!smb_acl_to_solaris_acl(theacl, &solaris_acl, &count,
SMB_ACL_TYPE_ACCESS))
{
DEBUG(10, ("conversion smb_acl -> solaris_acl failed (%s).\n",
/*
* delete the default ACL of a directory
*
- * This is achieved by fetching the access ACL and rewriting it
- * directly, via the solaris system call: the SETACL call on
+ * This is achieved by fetching the access ACL and rewriting it
+ * directly, via the solaris system call: the SETACL call on
* directories writes both the access and the default ACL as provided.
*
* XXX: posix acl_delete_def_file returns an error if
* the file referred to by path is not a directory.
- * this function does not complain but the actions
+ * this function does not complain but the actions
* have no effect on a file other than a directory.
* But sys_acl_delete_default_file is only called in
* smbd/posixacls.c after having checked that the file
int count;
DEBUG(10, ("entering solarisacl_sys_acl_delete_def_file.\n"));
-
- smb_acl = solarisacl_sys_acl_get_file(handle, path,
+
+ smb_acl = solarisacl_sys_acl_get_file(handle, path,
SMB_ACL_TYPE_ACCESS);
if (smb_acl == NULL) {
DEBUG(10, ("getting file acl failed!\n"));
goto done;
}
- if (!smb_acl_to_solaris_acl(smb_acl, &solaris_acl, &count,
+ if (!smb_acl_to_solaris_acl(smb_acl, &solaris_acl, &count,
SMB_ACL_TYPE_ACCESS))
{
DEBUG(10, ("conversion smb_acl -> solaris_acl failed.\n"));
if (ret != 0) {
DEBUG(10, ("settinge file acl failed!\n"));
}
-
+
done:
DEBUG(10, ("solarisacl_sys_acl_delete_def_file %s.\n",
((ret != 0) ? "failed" : "succeeded" )));
static SOLARIS_ACL_T solaris_acl_init(int count)
{
- SOLARIS_ACL_T solaris_acl =
+ SOLARIS_ACL_T solaris_acl =
(SOLARIS_ACL_T)SMB_MALLOC(sizeof(aclent_t) * count);
if (solaris_acl == NULL) {
errno = ENOMEM;
}
/*
- * Convert the SMB acl to the ACCESS or DEFAULT part of a
+ * Convert the SMB acl to the ACCESS or DEFAULT part of a
* solaris ACL, as desired.
*/
-static bool smb_acl_to_solaris_acl(SMB_ACL_T smb_acl,
- SOLARIS_ACL_T *solaris_acl, int *count,
+static bool smb_acl_to_solaris_acl(SMB_ACL_T smb_acl,
+ SOLARIS_ACL_T *solaris_acl, int *count,
SMB_ACL_TYPE_T type)
{
bool ret = False;
int i;
DEBUG(10, ("entering smb_acl_to_solaris_acl\n"));
-
+
*solaris_acl = NULL;
*count = 0;
}
switch(solaris_entry.a_type) {
case USER:
- DEBUG(10, ("got tag type USER with uid %u\n",
+ DEBUG(10, ("got tag type USER with uid %u\n",
(unsigned int)smb_entry->uid));
solaris_entry.a_id = (uid_t)smb_entry->uid;
break;
case GROUP:
- DEBUG(10, ("got tag type GROUP with gid %u\n",
+ DEBUG(10, ("got tag type GROUP with gid %u\n",
(unsigned int)smb_entry->gid));
solaris_entry.a_id = (uid_t)smb_entry->gid;
break;
DEBUG(10, ("adding default bit to solaris ace\n"));
solaris_entry.a_type |= ACL_DEFAULT;
}
-
- solaris_entry.a_perm =
+
+ solaris_entry.a_perm =
smb_perm_to_solaris_perm(smb_entry->a_perm);
DEBUG(10, ("assembled the following solaris ace:\n"));
DEBUGADD(10, (" - type: 0x%04x\n", solaris_entry.a_type));
DEBUGADD(10, (" - id: %u\n", (unsigned int)solaris_entry.a_id));
DEBUGADD(10, (" - perm: o%o\n", solaris_entry.a_perm));
- if (!solaris_add_to_acl(solaris_acl, count, &solaris_entry,
+ if (!solaris_add_to_acl(solaris_acl, count, &solaris_entry,
1, type))
{
DEBUG(10, ("error adding acl entry\n"));
ret = True;
goto done;
-
+
fail:
SAFE_FREE(*solaris_acl);
done:
return ret;
}
-/*
- * convert either the access or the default part of a
+/*
+ * convert either the access or the default part of a
* soaris acl to the SMB_ACL format.
*/
-static SMB_ACL_T solaris_acl_to_smb_acl(SOLARIS_ACL_T solaris_acl, int count,
+static SMB_ACL_T solaris_acl_to_smb_acl(SOLARIS_ACL_T solaris_acl, int count,
SMB_ACL_TYPE_T type)
{
SMB_ACL_T result;
for (i = 0; i < count; i++) {
SMB_ACL_ENTRY_T smb_entry;
SMB_ACL_PERM_T smb_perm;
-
+
if (!_IS_OF_TYPE(solaris_acl[i], type)) {
continue;
}
- result = SMB_REALLOC(result,
+ result = SMB_REALLOC(result,
sizeof(struct smb_acl_t) +
(sizeof(struct smb_acl_entry) *
(result->count + 1)));
sys_acl_set_qualifier(smb_entry, (void *)&solaris_acl[i].a_id);
smb_perm = solaris_perm_to_smb_perm(solaris_acl[i].a_perm);
if (sys_acl_set_permset(smb_entry, &smb_perm) != 0) {
- DEBUG(10, ("invalid permset given: %d\n",
+ DEBUG(10, ("invalid permset given: %d\n",
solaris_acl[i].a_perm));
goto fail;
}
result->count += 1;
}
goto done;
-
+
fail:
SAFE_FREE(result);
done:
DEBUG(10, ("smb_tag_to_solaris_tag\n"));
DEBUGADD(10, (" --> got smb tag 0x%04x\n", smb_tag));
-
+
switch (smb_tag) {
case SMB_ACL_USER:
solaris_tag = USER;
DEBUGADD(10, (" !!! unknown smb tag type 0x%04x\n", smb_tag));
break;
}
-
+
DEBUGADD(10, (" --> determined solaris tag 0x%04x\n", solaris_tag));
return solaris_tag;
SMB_ACL_TAG_T smb_tag = 0;
DEBUG(10, ("solaris_tag_to_smb_tag:\n"));
- DEBUGADD(10, (" --> got solaris tag 0x%04x\n", solaris_tag));
-
- solaris_tag &= ~ACL_DEFAULT;
+ DEBUGADD(10, (" --> got solaris tag 0x%04x\n", solaris_tag));
+
+ solaris_tag &= ~ACL_DEFAULT;
switch (solaris_tag) {
case USER:
smb_tag = SMB_ACL_MASK;
break;
default:
- DEBUGADD(10, (" !!! unknown solaris tag type: 0x%04x\n",
+ DEBUGADD(10, (" !!! unknown solaris tag type: 0x%04x\n",
solaris_tag));
break;
}
DEBUGADD(10, (" --> determined smb tag 0x%04x\n", smb_tag));
-
+
return smb_tag;
}
}
-static bool solaris_acl_get_file(const char *name, SOLARIS_ACL_T *solaris_acl,
+static bool solaris_acl_get_file(const char *name, SOLARIS_ACL_T *solaris_acl,
int *count)
{
bool result = False;
DEBUG(10, ("solaris_acl_get_file called for file '%s'\n", name));
-
- /*
+
+ /*
* The original code tries some INITIAL_ACL_SIZE
* and only did the GETACLCNT call upon failure
* (for performance reasons).
- * For the sake of simplicity, I skip this for now.
+ * For the sake of simplicity, I skip this for now.
*/
*count = acl(name, GETACLCNT, 0, NULL);
if (*count < 0) {
DEBUG(10, ("entering solaris_acl_get_fd\n"));
- /*
- * see solaris_acl_get_file for comment about omission
- * of INITIAL_ACL_SIZE...
+ /*
+ * see solaris_acl_get_file for comment about omission
+ * of INITIAL_ACL_SIZE...
*/
*count = facl(fd, GETACLCNT, 0, NULL);
if (*count < 0) {
* Add entries to a solaris ACL.
*
* Entries are directly added to the solarisacl parameter.
- * if memory allocation fails, this may result in solarisacl
- * being NULL. if the resulting acl is to be checked and is
+ * if memory allocation fails, this may result in solarisacl
+ * being NULL. if the resulting acl is to be checked and is
* not valid, it is kept in solarisacl but False is returned.
*
- * The type of ACEs (access/default) to be added to the ACL can
- * be selected via the type parameter.
+ * The type of ACEs (access/default) to be added to the ACL can
+ * be selected via the type parameter.
* I use the SMB_ACL_TYPE_T type here. Since SMB_ACL_TYPE_ACCESS
* is defined as "0", this means that one can only add either
- * access or default ACEs, not both at the same time. If it
+ * access or default ACEs, not both at the same time. If it
* should become necessary to add all of an ACL, one would have
* to replace this parameter by another type.
*/
static bool solaris_add_to_acl(SOLARIS_ACL_T *solaris_acl, int *count,
- SOLARIS_ACL_T add_acl, int add_count,
+ SOLARIS_ACL_T add_acl, int add_count,
SMB_ACL_TYPE_T type)
{
int i;
-
- if ((type != SMB_ACL_TYPE_ACCESS) && (type != SMB_ACL_TYPE_DEFAULT))
+
+ if ((type != SMB_ACL_TYPE_ACCESS) && (type != SMB_ACL_TYPE_DEFAULT))
{
DEBUG(10, ("invalid acl type given: %d\n", type));
errno = EINVAL;
if (!_IS_OF_TYPE(add_acl[i], type)) {
continue;
}
- ADD_TO_ARRAY(NULL, SOLARIS_ACE_T, add_acl[i],
+ ADD_TO_ARRAY(NULL, SOLARIS_ACE_T, add_acl[i],
solaris_acl, count);
if (solaris_acl == NULL) {
DEBUG(10, ("error enlarging acl.\n"));
}
-/*
+/*
* sort the ACL and check it for validity
*
* [original comment from lib/sysacls.c:]
- *
+ *
* if it's a minimal ACL with only 4 entries then we
* need to recalculate the mask permissions to make
* sure that they are the same as the GROUP_OBJ
{
int check_rc;
int check_which;
-
+
check_rc = aclcheck(solaris_acl, count, &check_which);
if (check_rc != 0) {
DEBUG(10, ("acl is not valid:\n"));
DEBUGADD(10, (" - which: %d\n", check_which));
if (check_which != -1) {
DEBUGADD(10, (" - invalid entry:\n"));
- DEBUGADD(10, (" * type: %d:\n",
+ DEBUGADD(10, (" * type: %d:\n",
solaris_acl[check_which].a_type));
DEBUGADD(10, (" * id: %d\n",
solaris_acl[check_which].a_id));
NTSTATUS vfs_solarisacl_init(void);
#endif
-
xattr_name, smb_fname->base_name));
if (fsp->base_fsp->fh->fd != -1) {
- if (SMB_VFS_FSETXATTR(
+ if (SMB_VFS_FSETXATTR(
fsp->base_fsp, xattr_name,
&null, sizeof(null),
flags & O_EXCL ? XATTR_CREATE : 0) == -1) {
-/*
+/*
* ensure meta data operations are performed synchronously
*
* Copyright (C) Andrew Tridgell 2007
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Samba
On those filesystems this module provides a way to perform those
- operations safely.
+ operations safely.
*/
/*
- most of the performance loss with this module is in fsync on close().
+ most of the performance loss with this module is in fsync on close().
You can disable that with syncops:onclose = no
*/
static bool sync_onclose;
}
syncops_sync_directory(parent1);
if (strcmp(parent1, parent2) != 0) {
- syncops_sync_directory(parent2);
+ syncops_sync_directory(parent2);
}
talloc_free(tmp_ctx);
}
return ret;
sync_onclose = lp_parm_bool(-1, "syncops", "onclose", true);
-
+
return ret;
}
/* prototypes for private functions first - for clarity */
static struct smb_acl_t *tru64_acl_to_smb_acl(const struct acl *tru64_acl);
-static bool tru64_ace_to_smb_ace(acl_entry_t tru64_ace,
+static bool tru64_ace_to_smb_ace(acl_entry_t tru64_ace,
struct smb_acl_entry *smb_ace);
static acl_t smb_acl_to_tru64_acl(const SMB_ACL_T smb_acl);
static acl_tag_t smb_tag_to_tru64(SMB_ACL_TAG_T smb_tag);
if (tru64_acl == NULL) {
return NULL;
}
-
+
result = tru64_acl_to_smb_acl(tru64_acl);
acl_free(tru64_acl);
return result;
acl_type_t the_acl_type;
acl_t tru64_acl;
- DEBUG(10, ("tru64acl_sys_acl_set_file called with name %s, type %d\n",
+ DEBUG(10, ("tru64acl_sys_acl_set_file called with name %s, type %d\n",
name, type));
switch(type) {
/* private functions */
-static struct smb_acl_t *tru64_acl_to_smb_acl(const struct acl *tru64_acl)
+static struct smb_acl_t *tru64_acl_to_smb_acl(const struct acl *tru64_acl)
{
struct smb_acl_t *result;
acl_entry_t entry;
DEBUG(10, ("Hi! This is tru64_acl_to_smb_acl.\n"));
-
+
if ((result = SMB_MALLOC_P(struct smb_acl_t)) == NULL) {
DEBUG(0, ("SMB_MALLOC_P failed in tru64_acl_to_smb_acl\n"));
errno = ENOMEM;
}
while ((entry = acl_get_entry((struct acl *)tru64_acl)) != NULL) {
result = SMB_REALLOC(result, sizeof(struct smb_acl_t) +
- (sizeof(struct smb_acl_entry) *
+ (sizeof(struct smb_acl_entry) *
(result->count + 1)));
if (result == NULL) {
DEBUG(0, ("SMB_REALLOC failed in tru64_acl_to_smb_acl\n"));
return NULL;
}
-static bool tru64_ace_to_smb_ace(acl_entry_t tru64_ace,
- struct smb_acl_entry *smb_ace)
+static bool tru64_ace_to_smb_ace(acl_entry_t tru64_ace,
+ struct smb_acl_entry *smb_ace)
{
acl_tag_t tru64_tag;
acl_permset_t permset;
DEBUG(0, ("acl_get_tag_type failed: %s\n", strerror(errno)));
return False;
}
-
- /* On could set the tag type directly to save a function call,
+
+ /* On could set the tag type directly to save a function call,
* but I like this better... */
smb_tag_type = tru64_tag_to_smb(tru64_tag);
if (smb_tag_type == 0) {
return False;
}
if (sys_acl_set_tag_type(smb_ace, smb_tag_type) != 0) {
- DEBUG(3, ("sys_acl_set_tag_type failed: %s\n",
+ DEBUG(3, ("sys_acl_set_tag_type failed: %s\n",
strerror(errno)));
return False;
}
return True;
}
-static acl_t smb_acl_to_tru64_acl(const SMB_ACL_T smb_acl)
+static acl_t smb_acl_to_tru64_acl(const SMB_ACL_T smb_acl)
{
acl_t result;
acl_entry_t tru64_entry;
int i;
char *acl_text;
ssize_t acl_text_len;
-
+
/* The tru64 acl_init function takes a size_t value
- * instead of a count of entries (as with posix).
+ * instead of a count of entries (as with posix).
* the size parameter "Specifies the size of the working
- * storage in bytes" (according to the man page).
- * But it is unclear to me, how this size is to be
- * calculated.
+ * storage in bytes" (according to the man page).
+ * But it is unclear to me, how this size is to be
+ * calculated.
*
- * It should not matter, since acl_create_entry enlarges
+ * It should not matter, since acl_create_entry enlarges
* the working storage at need. ... */
DEBUG(10, ("Hi! This is smb_acl_to_tru64_acl.\n"));
DEBUG(3, ("acl_init failed!\n"));
goto fail;
}
-
+
DEBUGADD(10, ("parsing acl entries...\n"));
for (i = 0; i < smb_acl->count; i++) {
/* XYZ - maybe eliminate this direct access? */
DEBUGADD(10, (" - acl type ACL_MASK: not implemented on Tru64 ==> skipping\n"));
continue;
}
-
+
tru64_entry = acl_create_entry(&result);
if (tru64_entry == NULL) {
- DEBUG(3, ("acl_create_entry failed: %s\n",
+ DEBUG(3, ("acl_create_entry failed: %s\n",
strerror(errno)));
goto fail;
}
strerror(errno)));
goto fail;
}
-
+
switch (smb_entry->a_type) {
case SMB_ACL_USER:
- if (acl_set_qualifier(tru64_entry,
- (int *)&smb_entry->uid) != 0)
+ if (acl_set_qualifier(tru64_entry,
+ (int *)&smb_entry->uid) != 0)
{
DEBUG(3, ("acl_set_qualifier failed: %s\n",
strerror(errno)));
DEBUGADD(10, (" - setting uid to %d\n", smb_entry->uid));
break;
case SMB_ACL_GROUP:
- if (acl_set_qualifier(tru64_entry,
+ if (acl_set_qualifier(tru64_entry,
(int *)&smb_entry->gid) != 0)
{
DEBUG(3, ("acl_set_qualifier failed: %s\n",
static acl_perm_t smb_permset_to_tru64(SMB_ACL_PERM_T smb_permset)
{
/* originally, I thought that acl_clear_perm was the
- * proper way to reset the permset to 0. but without
+ * proper way to reset the permset to 0. but without
* initializing it to 0, acl_clear_perm fails.
* so probably, acl_clear_perm is not necessary here... ?! */
acl_perm_t tru64_permset = 0;
NTSTATUS vfs_tru64acl_init(void);
#endif
-
(c) Alexander Bokovoy, 2007, 2008
(c) Andrew Tridgell, 2007, 2008
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
where <operation> is currently 'offline' to set offline status of the <filepath>
tsmsm: online ratio = ratio to check reported size against actual file size (0.5 by default)
- tsmsm: attribute name = name of DMAPI attribute that is present when a file is offline.
+ tsmsm: attribute name = name of DMAPI attribute that is present when a file is offline.
Default is "IBMobj" (which is what GPFS uses)
The TSMSM VFS module tries to avoid calling expensive DMAPI calls with some heuristics
#endif
#ifndef _ISOC99_SOURCE
-#define _ISOC99_SOURCE
+#define _ISOC99_SOURCE
#endif
-#include <math.h>
+#include <math.h>
/* optimisation tunables - used to avoid the DMAPI slow path */
#define FILE_IS_ONLINE_RATIO 0.5
TALLOC_FREE(*tsmd);
}
-/*
+/*
called when a client connects to a share
*/
static int tsmsm_connect(struct vfs_handle_struct *handle,
}
tsmname = (handle->param ? handle->param : "tsmsm");
-
+
/* Get 'hsm script' and 'dmapi attribute' parameters to tsmd context */
tsmd->hsmscript = lp_parm_talloc_string(SNUM(handle->conn), tsmname,
"hsm script", NULL);
talloc_steal(tsmd, tsmd->hsmscript);
-
- tsmd->attrib_name = lp_parm_talloc_string(SNUM(handle->conn), tsmname,
+
+ tsmd->attrib_name = lp_parm_talloc_string(SNUM(handle->conn), tsmname,
"dmapi attribute", DM_ATTRIB_OBJECT);
talloc_steal(tsmd, tsmd->attrib_name);
-
- tsmd->attrib_value = lp_parm_talloc_string(SNUM(handle->conn), "tsmsm",
+
+ tsmd->attrib_value = lp_parm_talloc_string(SNUM(handle->conn), "tsmsm",
"dmapi value", NULL);
talloc_steal(tsmd, tsmd->attrib_value);
-
+
/* retrieve 'online ratio'. In case of error default to FILE_IS_ONLINE_RATIO */
- fres = lp_parm_const_string(SNUM(handle->conn), tsmname,
+ fres = lp_parm_const_string(SNUM(handle->conn), tsmname,
"online ratio", NULL);
if (fres == NULL) {
tsmd->online_ratio = FILE_IS_ONLINE_RATIO;
return 0;
}
-static bool tsmsm_is_offline(struct vfs_handle_struct *handle,
+static bool tsmsm_is_offline(struct vfs_handle_struct *handle,
const char *path,
SMB_STRUCT_STAT *stbuf) {
struct tsmsm_struct *tsmd = (struct tsmsm_struct *) handle->data;
return false;
}
- /* using POSIX capabilities does not work here. It's a slow path, so
- * become_root() is just as good anyway (tridge)
+ /* using POSIX capabilities does not work here. It's a slow path, so
+ * become_root() is just as good anyway (tridge)
*/
/* Also, AIX has DMAPI but no POSIX capablities support. In this case,
/* go the slow DMAPI route */
if (dm_path_to_handle((char*)path, &dmhandle, &dmhandle_len) != 0) {
- DEBUG(2,("dm_path_to_handle failed - assuming offline (%s) - %s\n",
+ DEBUG(2,("dm_path_to_handle failed - assuming offline (%s) - %s\n",
path, strerror(errno)));
offline = true;
goto done;
do {
lerrno = 0;
- ret = dm_get_dmattr(*dmsession_id, dmhandle, dmhandle_len,
+ ret = dm_get_dmattr(*dmsession_id, dmhandle, dmhandle_len,
DM_NO_TOKEN, &dmname, buflen, buf, &rlen);
if (ret == -1 && errno == EINVAL) {
DEBUG(0, ("Stale DMAPI session, re-creating it.\n"));
if (dmapi_new_session()) {
dmsession_id = dmapi_get_current_session();
} else {
- DEBUG(0,
- ("Unable to re-create DMAPI session, assuming offline (%s) - %s\n",
+ DEBUG(0,
+ ("Unable to re-create DMAPI session, assuming offline (%s) - %s\n",
path, strerror(errno)));
offline = true;
dm_handle_free(dmhandle, dmhandle_len);
/* check if we need a specific attribute value */
if (tsmd->attrib_value != NULL) {
- offline = (ret == 0 && rlen == buflen &&
+ offline = (ret == 0 && rlen == buflen &&
memcmp(buf, tsmd->attrib_value, buflen) == 0);
} else {
/* its offline if the specified DMAPI attribute exists */
ret = 0;
- dm_handle_free(dmhandle, dmhandle_len);
+ dm_handle_free(dmhandle, dmhandle_len);
done:
talloc_free(buf);
return false;
}
-static ssize_t tsmsm_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp,
+static ssize_t tsmsm_aio_return(struct vfs_handle_struct *handle, struct files_struct *fsp,
SMB_STRUCT_AIOCB *aiocb)
{
ssize_t result;
errno = ENOSYS;
return -1;
}
-
+
return SMB_VFS_NEXT_SENDFILE(handle, tofd, fsp, hdr, offset, n);
}
/* We do overload pread to allow notification when file becomes online after offline status */
/* We don't intercept SMB_VFS_READ here because all file I/O now goes through SMB_VFS_PREAD instead */
-static ssize_t tsmsm_pread(struct vfs_handle_struct *handle, struct files_struct *fsp,
+static ssize_t tsmsm_pread(struct vfs_handle_struct *handle, struct files_struct *fsp,
void *data, size_t n, SMB_OFF_T offset) {
ssize_t result;
bool notify_online = tsmsm_aio_force(handle, fsp);
result = SMB_VFS_NEXT_PREAD(handle, fsp, data, n, offset);
if((result != -1) && notify_online) {
- /* We can't actually force AIO at this point (came here not from reply_read_and_X)
+ /* We can't actually force AIO at this point (came here not from reply_read_and_X)
what we can do is to send notification that file became online
*/
notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED,
return result;
}
-static ssize_t tsmsm_pwrite(struct vfs_handle_struct *handle, struct files_struct *fsp,
+static ssize_t tsmsm_pwrite(struct vfs_handle_struct *handle, struct files_struct *fsp,
const void *data, size_t n, SMB_OFF_T offset) {
ssize_t result;
bool notify_online = tsmsm_aio_force(handle, fsp);
result = SMB_VFS_NEXT_PWRITE(handle, fsp, data, n, offset);
if((result != -1) && notify_online) {
- /* We can't actually force AIO at this point (came here not from reply_read_and_X)
+ /* We can't actually force AIO at this point (came here not from reply_read_and_X)
what we can do is to send notification that file became online
*/
notify_fname(handle->conn, NOTIFY_ACTION_MODIFIED,
return result;
}
-static int tsmsm_set_offline(struct vfs_handle_struct *handle,
+static int tsmsm_set_offline(struct vfs_handle_struct *handle,
const char *path) {
struct tsmsm_struct *tsmd = (struct tsmsm_struct *) handle->data;
int result = 0;
-/*
+/*
Unix SMB/CIFS implementation.
Samba module with developer tools
Copyright (C) Andrew Tridgell 2001
Copyright (C) Jelmer Vernooij 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 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
int i;
int done = 0;
for (i=0;weird_table[i].from;i++) {
- if (strncmp((*inbuf),
- weird_table[i].to,
+ if (strncmp((*inbuf),
+ weird_table[i].to,
weird_table[i].len) == 0) {
if (*inbytesleft < weird_table[i].len) {
DEBUG(0,("ERROR: truncated weird string\n"));
errno = E2BIG;
return -1;
}
-
+
return 0;
}
DEBUG(0,("No room for weird character\n"));
/* smb_panic("weird_push"); */
} else {
- memcpy(*outbuf, weird_table[i].to,
+ memcpy(*outbuf, weird_table[i].to,
weird_table[i].len);
(*inbytesleft) -= 2;
(*outbytesleft) -= weird_table[i].len;
errno = E2BIG;
return -1;
}
-
+
return ir_count;
}
#define DBGC_CLASS DBGC_MSDFS
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
/**********************************************************************
Parse a DFS pathname of the form \hostname\service\reqpath
conn->connectpath, pdp->reqpath));
/*
- * Note the unix path conversion here we're doing we can
+ * Note the unix path conversion here we're doing we can
* throw away. We're looking for a symlink for a dfs
* resolution, if we don't find it we'll do another
* unix_convert later in the codepath.
/*
* It's an msdfs proxy share. Redirect to
- * the configured target share.
- */
+ * the configured target share.
+ */
jucn->referral_count = 1;
if ((ref = TALLOC_ZERO_P(ctx, struct referral)) == NULL) {
-/*
+/*
Unix SMB/CIFS implementation.
negprot reply code
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Volker Lendecke 2007
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/auth/spnego.h"
extern fstring remote_proto;
struct smbd_server_connection *sconn = smbd_server_conn;
sconn->smb1.negprot.encrypted_passwords = lp_encrypted_passwords();
-
+
if (lp_security()>=SEC_USER) {
secword |= NEGOTIATE_SECURITY_USER_LEVEL;
}
sconn->smb1.negprot.encrypted_passwords = lp_encrypted_passwords();
/* Check the flags field to see if this is Vista.
- WinXP sets it and Vista does not. But we have to
+ WinXP sets it and Vista does not. But we have to
distinguish from NT which doesn't set it either. */
if ( (req->flags2 & FLAGS2_EXTENDED_SECURITY) &&
/* do spnego in user level security if the client
supports it and we can do encrypted passwords */
-
+
if (sconn->smb1.negprot.encrypted_passwords &&
(lp_security() != SEC_SHARE) &&
lp_use_spnego() &&
SSVAL(req->outbuf, smb_flg2,
req->flags2 | FLAGS2_EXTENDED_SECURITY);
}
-
+
capabilities |= CAP_NT_SMBS|CAP_RPC_REMOTE_APIS|CAP_UNICODE;
if (lp_unix_extensions()) {
capabilities |= CAP_UNIX;
}
-
+
if (lp_large_readwrite() && (SMB_OFF_T_BITS == 64))
capabilities |= CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_W2K_SMBS;
-
+
if (SMB_OFF_T_BITS == 64)
capabilities |= CAP_LARGE_FILES;
if (lp_readraw() && lp_writeraw())
capabilities |= CAP_RAW_MODE;
-
+
if (lp_nt_status_support())
capabilities |= CAP_STATUS32;
-
+
if (lp_host_msdfs())
capabilities |= CAP_DFS;
-
+
if (lp_security() >= SEC_USER) {
secword |= NEGOTIATE_SECURITY_USER_LEVEL;
}
}
if (lp_server_signing()) {
- if (lp_security() >= SEC_USER) {
+ if (lp_security() >= SEC_USER) {
secword |= NEGOTIATE_SECURITY_SIGNATURES_ENABLED;
/* No raw mode with smb signing. */
capabilities &= ~CAP_RAW_MODE;
SSVAL(req->outbuf,smb_vwv0,choice);
SCVAL(req->outbuf,smb_vwv1,secword);
-
+
set_Protocol(PROTOCOL_NT1);
-
+
SSVAL(req->outbuf,smb_vwv1+1,lp_maxmux()); /* maxmpx */
SSVAL(req->outbuf,smb_vwv2+1,1); /* num vcs */
SIVAL(req->outbuf,smb_vwv3+1,
SIVAL(req->outbuf,smb_vwv9+1,capabilities); /* capabilities */
put_long_date((char *)req->outbuf+smb_vwv11+1,t);
SSVALS(req->outbuf,smb_vwv15+1,set_server_zone_offset(t)/60);
-
+
p = q = smb_buf(req->outbuf);
if (!negotiate_spnego) {
/* Create a token value and add it to the outgoing packet. */
SCVAL(req->outbuf,smb_vwv16+1, 0);
DEBUG(3,("using SPNEGO\n"));
}
-
+
SSVAL(req->outbuf,smb_vwv17, p - q); /* length of challenge+domain
* strings */
Protocol WfWg Win95 WinNT Win2K OS/2 Vista
PC NETWORK PROGRAM 1.0 1 1 1 1 1 1
XENIX CORE 2 2
- MICROSOFT NETWORKS 3.0 2 2
- DOS LM1.2X002 3 3
+ MICROSOFT NETWORKS 3.0 2 2
+ DOS LM1.2X002 3 3
MICROSOFT NETWORKS 1.03 3
- DOS LANMAN2.1 4 4
+ DOS LANMAN2.1 4 4
LANMAN1.0 4 2 3 2
Windows for Workgroups 3.1a 5 5 5 3 3
LM1.2X002 6 4 4 4
* tim@fsg.com 09/29/95
* Win2K added by matty 17/7/99
*/
-
+
#define ARCH_WFWG 0x3 /* This is a fudge because WfWg is like Win95 */
#define ARCH_WIN95 0x2
#define ARCH_WINNT 0x4
#define ARCH_SAMBA 0x20
#define ARCH_CIFSFS 0x40
#define ARCH_VISTA 0x8C /* Vista is like XP/2K */
-
+
#define ARCH_ALL 0x7F
-
+
/* List of supported protocols, most desired first */
static const struct {
const char *proto_name;
{"LANMAN1.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
{"MICROSOFT NETWORKS 3.0", "LANMAN1", reply_lanman1, PROTOCOL_LANMAN1},
{"MICROSOFT NETWORKS 1.03", "COREPLUS", reply_coreplus, PROTOCOL_COREPLUS},
- {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
+ {"PC NETWORK PROGRAM 1.0", "CORE", reply_corep, PROTOCOL_CORE},
{NULL,NULL,NULL,0},
};
arch &= ( ARCH_WIN95 | ARCH_WINNT | ARCH_WIN2K
| ARCH_CIFSFS);
else if (strcsequal(cliprotos[i], "SMB 2.001"))
- arch = ARCH_VISTA;
+ arch = ARCH_VISTA;
else if (strcsequal(cliprotos[i], "LANMAN2.1"))
arch &= ( ARCH_WINNT | ARCH_WIN2K | ARCH_OS2 );
else if (strcsequal(cliprotos[i], "LM1.2X002"))
set_remote_arch(RA_WINNT);
break;
case ARCH_WIN2K:
- /* Vista may have been set in the negprot so don't
+ /* Vista may have been set in the negprot so don't
override it here */
if ( get_remote_arch() != RA_VISTA )
set_remote_arch(RA_WIN2K);
set_remote_arch(RA_UNKNOWN);
break;
}
-
+
/* possibly reload - change of architecture */
- reload_services(True);
-
- /* moved from the netbios session setup code since we don't have that
+ reload_services(True);
+
+ /* moved from the netbios session setup code since we don't have that
when the client connects to port 445. Of course there is a small
window where we are listening to messages -- jerry */
serverid_register_self(FLAG_MSG_GENERAL|FLAG_MSG_SMBD
|FLAG_MSG_PRINT_GENERAL);
-
+
/* Check for protocols, most desirable first */
for (protocol = 0; supported_protocols[protocol].proto_name; protocol++) {
i = 0;
if(choice != -1)
break;
}
-
+
if(choice != -1) {
fstrcpy(remote_proto,supported_protocols[protocol].short_name);
- reload_services(True);
+ reload_services(True);
supported_protocols[protocol].proto_reply_fn(req, choice);
DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name));
} else {
reply_outbuf(req, 1, 0);
SSVAL(req->outbuf, smb_vwv0, choice);
}
-
+
DEBUG( 5, ( "negprot index=%d\n", choice ) );
if ((lp_server_signing() == Required) && (get_Protocol() < PROTOCOL_NT1)) {
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
struct notify_change_request {
struct notify_change_request *prev, *next;
}
string_replace(tmp, '/', '\\');
- change->name = tmp;
+ change->name = tmp;
change->action = action;
fsp->notify->num_changes += 1;
}
struct sys_notify_context *sys_notify_context_create(connection_struct *conn,
- TALLOC_CTX *mem_ctx,
+ TALLOC_CTX *mem_ctx,
struct event_context *ev)
{
struct sys_notify_context *ctx;
NTSTATUS sys_notify_watch(struct sys_notify_context *ctx,
struct notify_entry *e,
- void (*callback)(struct sys_notify_context *ctx,
+ void (*callback)(struct sys_notify_context *ctx,
void *private_data,
struct notify_event *ev),
void *private_data, void *handle)
return SMB_VFS_NOTIFY_WATCH(ctx->conn, ctx, e, callback, private_data,
handle);
}
-
-/*
+/*
Unix SMB/CIFS implementation.
Copyright (C) Andrew Tridgell 2006
struct inotify_watch_context *next, *prev;
struct inotify_private *in;
int wd;
- void (*callback)(struct sys_notify_context *ctx,
+ void (*callback)(struct sys_notify_context *ctx,
void *private_data,
struct notify_event *ev);
void *private_data;
FILE_NOTIFY_CHANGE_SECURITY))) {
return True;
}
- if ((e->mask & IN_MODIFY) &&
+ if ((e->mask & IN_MODIFY) &&
(w->filter & FILE_NOTIFY_CHANGE_ATTRIBUTES)) {
return True;
}
the cookies are used to correctly handle renames
*/
-static void inotify_dispatch(struct inotify_private *in,
- struct inotify_event *e,
+static void inotify_dispatch(struct inotify_private *in,
+ struct inotify_event *e,
uint32_t prev_cookie,
struct inotify_event *e2)
{
filenames, and thus can't know how much to allocate
otherwise
*/
- if (ioctl(in->fd, FIONREAD, &bufsize) != 0 ||
+ if (ioctl(in->fd, FIONREAD, &bufsize) != 0 ||
bufsize == 0) {
DEBUG(0,("No data on inotify fd?!\n"));
TALLOC_FREE(fde);
*/
NTSTATUS inotify_watch(struct sys_notify_context *ctx,
struct notify_entry *e,
- void (*callback)(struct sys_notify_context *ctx,
+ void (*callback)(struct sys_notify_context *ctx,
void *private_data,
struct notify_event *ev),
- void *private_data,
+ void *private_data,
void *handle_p)
{
struct inotify_private *in;
-/*
+/*
Unix SMB/CIFS implementation.
Copyright (C) Andrew Tridgell 2006
static NTSTATUS notify_remove_all(struct notify_context *notify,
const struct server_id *server);
-static void notify_handler(struct messaging_context *msg_ctx, void *private_data,
+static void notify_handler(struct messaging_context *msg_ctx, void *private_data,
uint32_t msg_type, struct server_id server_id, DATA_BLOB *data);
/*
talloc_free(). We need the messaging_ctx to allow for notifications
via internal messages
*/
-struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server,
+struct notify_context *notify_init(TALLOC_CTX *mem_ctx, struct server_id server,
struct messaging_context *messaging_ctx,
struct event_context *ev,
connection_struct *conn)
/* register with the messaging subsystem for the notify
message type */
- messaging_register(notify->messaging_ctx, notify,
+ messaging_register(notify->messaging_ctx, notify,
MSG_PVFS_NOTIFY, notify_handler);
notify->sys_notify_ctx = sys_notify_context_create(conn, notify, ev);
/*
handle incoming notify messages
*/
-static void notify_handler(struct messaging_context *msg_ctx, void *private_data,
+static void notify_handler(struct messaging_context *msg_ctx, void *private_data,
uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
{
struct notify_context *notify = talloc_get_type(private_data, struct notify_context);
}
}
- talloc_free(tmp_ctx);
+ talloc_free(tmp_ctx);
}
/*
callback from sys_notify telling us about changes from the OS
*/
-static void sys_notify_callback(struct sys_notify_context *ctx,
+static void sys_notify_callback(struct sys_notify_context *ctx,
void *ptr, struct notify_event *ev)
{
struct notify_list *listel = talloc_get_type(ptr, struct notify_list);
/* possibly expand the depths array */
if (depth >= notify->array->num_depths) {
- d = talloc_realloc(notify->array, notify->array->depth,
+ d = talloc_realloc(notify->array, notify->array->depth,
struct notify_depth, depth+1);
NT_STATUS_HAVE_NO_MEMORY(d);
for (i=notify->array->num_depths;i<=depth;i++) {
directory handle.
*/
NTSTATUS notify_add(struct notify_context *notify, struct notify_entry *e0,
- void (*callback)(void *, const struct notify_event *),
+ void (*callback)(void *, const struct notify_event *),
void *private_data)
{
struct notify_entry e = *e0;
to remove bits handled by the backend
*/
status = sys_notify_watch(notify->sys_notify_ctx, &e,
- sys_notify_callback, listel,
+ sys_notify_callback, listel,
&listel->sys_notify_handle);
if (NT_STATUS_IS_OK(status)) {
talloc_steal(listel, listel->sys_notify_handle);
}
if (i < d->num_entries-1) {
- memmove(&d->entries[i], &d->entries[i+1],
+ memmove(&d->entries[i], &d->entries[i+1],
sizeof(d->entries[i])*(d->num_entries-(i+1)));
}
d->num_entries--;
for (i=0;i<d->num_entries;i++) {
if (cluster_id_equal(server, &d->entries[i].server)) {
if (i < d->num_entries-1) {
- memmove(&d->entries[i], &d->entries[i+1],
+ memmove(&d->entries[i], &d->entries[i+1],
sizeof(d->entries[i])*(d->num_entries-(i+1)));
}
i--;
return ndr_map_error2ntstatus(ndr_err);
}
- status = messaging_send(notify->messaging_ctx, e->server,
+ status = messaging_send(notify->messaging_ctx, e->server,
MSG_PVFS_NOTIFY, &data);
talloc_free(tmp_ctx);
return status;
-/*
+/*
Unix SMB/CIFS implementation.
NT QUOTA suppport
Copyright (C) Stefan (metze) Metzmacher 2003
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
uint64_t ret = (uint64_t)0;
ret = (uint64_t)(in*bsize);
-
+
if (ret < in) {
/* we overflow */
ret = SMB_NTQUOTAS_NO_LIMIT;
static uint64_t limit_blk2inodes(uint64_t in)
{
uint64_t ret = (uint64_t)0;
-
+
ret = (uint64_t)(in/2);
-
+
if (ret == 0 && in != 0)
ret = (uint64_t)1;
- return ret;
+ return ret;
}
int vfs_get_ntquota(files_struct *fsp, enum SMB_QUOTA_TYPE qtype, DOM_SID *psid, SMB_NTQUOTA_STRUCT *qt)
if (ret!=0) {
return ret;
}
-
+
qt->usedspace = (uint64_t)D.curblocks*D.bsize;
qt->softlim = limit_unix2nt(D.softlimit, D.bsize);
qt->hardlim = limit_unix2nt(D.hardlimit, D.bsize);
qt->qflags = D.qflags;
-
+
return 0;
}
}
ret = SMB_VFS_SET_QUOTA(fsp->conn, qtype, id, &D);
-
+
return ret;
}
static bool allready_in_quota_list(SMB_NTQUOTA_LIST *qt_list, uid_t uid)
{
SMB_NTQUOTA_LIST *tmp_list = NULL;
-
+
if (!qt_list)
return False;
for (tmp_list=qt_list;tmp_list!=NULL;tmp_list=tmp_list->next) {
if (tmp_list->uid == uid) {
- return True;
+ return True;
}
}
tmp_list_ent->mem_ctx = mem_ctx;
DLIST_ADD((*qt_list),tmp_list_ent);
-
+
}
sys_endpwent();
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
extern const struct generic_mapping file_generic_mapping;
if (flags & EXTENDED_RESPONSE_REQUIRED) {
/* This is very strange. We
- * return 50 words, but only set
- * the wcnt to 42 ? It's definately
- * what happens on the wire....
- */
+ * return 50 words, but only set
+ * the wcnt to 42 ? It's definately
+ * what happens on the wire....
+ */
reply_outbuf(req, 50, 0);
SCVAL(req->outbuf,smb_wct,42);
} else {
SIVAL(p,0,FILE_GENERIC_ALL);
/*
* For pipes W2K3 seems to return
- * 0x12019B next.
- * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
- */
+ * 0x12019B next.
+ * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
+ */
SIVAL(p,4,(FILE_GENERIC_READ|FILE_GENERIC_WRITE)&~FILE_APPEND_DATA);
}
if (flags & EXTENDED_RESPONSE_REQUIRED) {
/* This is very strange. We
- * return 50 words, but only set
- * the wcnt to 42 ? It's definately
- * what happens on the wire....
- */
+ * return 50 words, but only set
+ * the wcnt to 42 ? It's definately
+ * what happens on the wire....
+ */
reply_outbuf(req, 50, 0);
SCVAL(req->outbuf,smb_wct,42);
} else {
SIVAL(p,0,FILE_GENERIC_ALL);
/*
* For pipes W2K3 seems to return
- * 0x12019B next.
- * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
- */
+ * 0x12019B next.
+ * This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
+ */
SIVAL(p,4,(FILE_GENERIC_READ|FILE_GENERIC_WRITE)&~FILE_APPEND_DATA);
}
isFSctl = CVAL(*ppsetup, 6);
compfilter = CVAL(*ppsetup, 7);
- DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n",
+ DEBUG(10,("call_nt_transact_ioctl: function[0x%08X] FID[0x%04X] isFSctl[0x%02X] compfilter[0x%02X]\n",
function, fidnum, isFSctl, compfilter));
fsp=file_fsp(req, fidnum);
if (SMB_VFS_GET_SHADOW_COPY_DATA(fsp, shadow_data, labels)!=0) {
talloc_destroy(shadow_data->mem_ctx);
if (errno == ENOSYS) {
- DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n",
+ DEBUG(5,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, not supported.\n",
conn->connectpath));
reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
return;
} else {
- DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n",
+ DEBUG(0,("FSCTL_GET_SHADOW_COPY_DATA: connectpath %s, failed.\n",
conn->connectpath));
reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
return;
-/*
+/*
Unix SMB/CIFS implementation.
file opening and share modes
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jeremy Allison 2001-2004
Copyright (C) Volker Lendecke 2005
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
extern const struct generic_mapping file_generic_mapping;
NTSTATUS status = NT_STATUS_OK;
#ifdef O_NOFOLLOW
- /*
+ /*
* Never follow symlinks on a POSIX client. The
* client should be doing this.
*/
/* Check permissions */
/*
- * This code was changed after seeing a client open request
+ * This code was changed after seeing a client open request
* containing the open mode of (DENY_WRITE/read-only) with
* the 'create if not exist' bit set. The previous code
* would fail to open the file read only on a read-only share
share_access, FILE_SHARE_WRITE);
CHECK_MASK(2, access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
entry->share_access, FILE_SHARE_WRITE);
-
+
CHECK_MASK(3, entry->access_mask, FILE_READ_DATA | FILE_EXECUTE,
share_access, FILE_SHARE_READ);
CHECK_MASK(4, access_mask, FILE_READ_DATA | FILE_EXECUTE,
/*
* Check if the share modes will give us access.
*/
-
+
#if defined(DEVELOPER)
for(i = 0; i < lck->num_share_modes; i++) {
validate_my_share_entries(i, &lck->share_modes[i]);
return NT_STATUS_SHARING_VIOLATION;
}
}
-
+
return NT_STATUS_OK;
}
/*
* Match what was requested (fsp->oplock_type) with
- * what was found in the existing share modes.
- */
+ * what was found in the existing share modes.
+ */
if (!valid_entry) {
/* All entries are placeholders or deferred.
noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
- if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
+ if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
(noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
*returned_unx_mode = new_unx_mode;
} else {
case OPENX_FILE_EXISTS_OPEN|OPENX_FILE_CREATE_IF_NOT_EXIST:
create_disposition = FILE_OPEN_IF;
break;
-
+
case OPENX_FILE_EXISTS_TRUNCATE:
create_disposition = FILE_OVERWRITE;
break;
"open_func 0x%x\n", (unsigned int)open_func));
return False;
}
-
+
/* Create the NT compatible share modes. */
switch (GET_DENY_MODE(deny_mode)) {
case DENY_ALL:
uint32 create_options, /* options such as delete on close. */
uint32 new_dos_attributes, /* attributes used for new file. */
int oplock_request, /* internal Samba oplock codes. */
- /* Information (FILE_EXISTS etc.) */
+ /* Information (FILE_EXISTS etc.) */
uint32_t private_flags, /* Samba specific flags. */
int *pinfo,
files_struct *fsp)
status = calculate_access_mask(conn, smb_fname, file_existed,
access_mask,
- &access_mask);
+ &access_mask);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(10, ("open_file_ntcreate: calculate_access_mask "
"on file %s returned %s\n",
if (SMB_VFS_STAT(conn, smb_dname) != 0) {
return map_nt_error_from_unix(errno);
}
-
+
break;
case FILE_CREATE:
info = FILE_WAS_OPENED;
status = NT_STATUS_OK;
}
-
+
break;
case FILE_SUPERSEDE:
/*
* Setup the files_struct for it.
*/
-
+
fsp->mode = smb_dname->st.st_ex_mode;
fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
-/*
+/*
Unix SMB/CIFS implementation.
oplock processing
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Jeremy Allison 1998 - 2001
Copyright (C) Volker Lendecke 2005
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define DBGC_CLASS DBGC_LOCKING
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
/****************************************************************************
Get the number of current exclusive oplocks.
if (fsp == NULL) {
/* We hit a race here. Break messages are sent, and before we
- * get to process this message, we have closed the file.
+ * get to process this message, we have closed the file.
* No need to reply as this is an async message. */
DEBUG(3, ("process_oplock_async_level2_break_message: Did not find fsp, ignoring\n"));
return;
return;
}
- if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
+ if ((global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
!(msg.op_type & FORCE_OPLOCK_BREAK_TO_NONE) &&
!(koplocks && !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) &&
lp_level2_oplocks(SNUM(fsp->conn))) {
DATA_BLOB *data)
{
struct share_mode_entry msg;
-
+
if (data->data == NULL) {
DEBUG(0, ("Got NULL buffer\n"));
return;
return;
}
- DEBUG(10,("release_level_2_oplocks_on_change: num_share_modes = %d\n",
+ DEBUG(10,("release_level_2_oplocks_on_change: num_share_modes = %d\n",
lck->num_share_modes ));
for(i = 0; i < lck->num_share_modes; i++) {
/*
* Deal with a race condition when breaking level2
- * oplocks. Don't send all the messages and release
- * the lock, this allows someone else to come in and
- * get a level2 lock before any of the messages are
- * processed, and thus miss getting a break message.
- * Ensure at least one entry (the one we're breaking)
- * is processed immediately under the lock and becomes
- * set as NO_OPLOCK to stop any waiter getting a level2.
- * Bugid #5980.
- */
+ * oplocks. Don't send all the messages and release
+ * the lock, this allows someone else to come in and
+ * get a level2 lock before any of the messages are
+ * processed, and thus miss getting a break message.
+ * Ensure at least one entry (the one we're breaking)
+ * is processed immediately under the lock and becomes
+ * set as NO_OPLOCK to stop any waiter getting a level2.
+ * Bugid #5980.
+ */
if (procid_is_me(&share_entry->pid)) {
wait_before_sending_break();
Unix SMB/CIFS implementation.
IRIX kernel oplock processing
Copyright (C) Andrew Tridgell 1992-1998
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define DBGC_CLASS DBGC_LOCKING
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#if HAVE_KERNEL_OPLOCKS_IRIX
(unsigned int)os.os_dev, (double)os.os_ino ));
return NULL;
}
-
+
DEBUG(5,("irix_oplock_receive_message: kernel oplock break request "
"received for file_id %s gen_id = %ul",
file_id_string_tos(&fsp->file_id),
if(errno != EAGAIN) {
DEBUG(0,("irix_set_kernel_oplock: Unable to get "
"kernel oplock on file %s, file_id %s "
- "gen_id = %ul. Error was %s\n",
+ "gen_id = %ul. Error was %s\n",
fsp_str_dbg(fsp),
file_id_string_tos(&fsp->file_id),
fsp->fh->gen_id,
}
return False;
}
-
+
DEBUG(10,("irix_set_kernel_oplock: got kernel oplock on file %s, file_id = %s "
"gen_id = %ul\n",
fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id),
-/*
+/*
Unix SMB/CIFS implementation.
kernel oplock processing for Linux
Copyright (C) Andrew Tridgell 2000
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define DBGC_CLASS DBGC_LOCKING
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#if HAVE_KERNEL_OPLOCKS_LINUX
set_effective_capability(LEASE_CAPABILITY);
}
-/*
+/*
* Call to set the kernel lease signal handler
*/
int linux_set_lease_sighandler(int fd)
strerror(errno)));
return False;
}
-
+
DEBUG(3,("linux_set_kernel_oplock: got kernel oplock on file %s, "
"file_id = %s gen_id = %lu\n",
fsp_str_dbg(fsp), file_id_string_tos(&fsp->file_id),
#if HAVE_ONEFS
#include "oplock_onefs.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include <ifs/ifs_syscalls.h>
#include <isi_ecs/isi_ecs_oplocks.h>
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
enum server_allocated_state { SERVER_ALLOCATED_REQUIRED_YES,
SERVER_ALLOCATED_REQUIRED_NO,
-/*
+/*
Unix SMB/CIFS implementation.
Pipe SMB reply routines
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Luke Kenneth Casson Leighton 1996-1998
Copyright (C) Paul Ashton 1997-1998.
Copyright (C) Jeremy Allison 2005.
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
state->outbuf = NULL;
srv_set_message((char *)req->outbuf, 12, nread, False);
-
+
SSVAL(req->outbuf,smb_vwv5,nread);
SSVAL(req->outbuf,smb_vwv6,
req_wct_ofs(req)
+ 12 * sizeof(uint16_t) /* vwv */
+ 2); /* the buflen field */
SSVAL(req->outbuf,smb_vwv11,state->smb_maxcnt);
-
+
DEBUG(3,("readX-IPC min=%d max=%d nread=%d\n",
state->smb_mincnt, state->smb_maxcnt, (int)nread));
}
DEBUG(3,("unpack_nt_owners: owner sid mapped to uid %u\n",
(unsigned int)*puser ));
- }
+ }
/*
* Don't immediately fail if the group sid cannot be validated.
}
DEBUG(3,("unpack_nt_owners: group sid mapped to gid %u\n",
(unsigned int)*pgrp));
- }
+ }
DEBUG(5,("unpack_nt_owners: owner_sids validated.\n"));
or_bits = lp_force_security_mode(params->service);
}
- /* Now bounce them into the S_USR space. */
+ /* Now bounce them into the S_USR space. */
switch(type) {
case S_IRUSR:
/* Ensure owner has read access. */
}
/****************************************************************************
- A well formed POSIX file or default ACL has at least 3 entries, a
+ A well formed POSIX file or default ACL has at least 3 entries, a
SMB_ACL_USER_OBJ, SMB_ACL_GROUP_OBJ, SMB_ACL_OTHER_OBJ.
In addition, the owner must always have at least read access.
When using this call on get_acl, the pst struct is valid and contains
/*
* Convert GENERIC bits to specific bits.
*/
-
+
se_map_generic(&psa->access_mask, &file_generic_mapping);
psa->access_mask &= (UNIX_ACCESS_NONE|FILE_ALL_ACCESS);
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
return False;
- }
+ }
if( DEBUGLVL( 10 )) {
dbgtext("create_canon_ace_lists: adding dir ACL:\n");
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
return False;
- }
+ }
if( DEBUGLVL( 10 )) {
dbgtext("create_canon_ace_lists: adding file ACL:\n");
entry as a mask on all following allow entries. Finally, delete
the Everyone DENY entry (we have applied it to everything possible).
- In addition, in this pass we remove any DENY entries that have
+ In addition, in this pass we remove any DENY entries that have
no permissions (ie. they are a DENY nothing).
---------------------------------------------------------------------------
Second pass - only deal with deny user entries.
for (allow_ace_p = curr_ace->next; allow_ace_p; allow_ace_p = allow_ace_p->next) {
- /*
+ /*
* Only mask off allow entries.
*/
process_deny_list(fsp->conn, &dir_ace);
/*
- * A well formed POSIX file or default ACL has at least 3 entries, a
+ * A well formed POSIX file or default ACL has at least 3 entries, a
* SMB_ACL_USER_OBJ, SMB_ACL_GROUP_OBJ, SMB_ACL_OTHER_OBJ
* and optionally a mask entry. Ensure this is the case.
*/
the_acl);
unbecome_root();
if (sret == 0) {
- ret = True;
+ ret = True;
}
}
}
/****************************************************************************
-
+
****************************************************************************/
SMB_ACL_T free_empty_sys_acl(connection_struct *conn, SMB_ACL_T the_acl)
* would lead to usability problems under Windows: The Creator entries
* are only available in browse lists of directories and not for files;
* additionally the identity of the owning group couldn't be determined.
- * We therefore use those identities only for Default ACLs.
+ * We therefore use those identities only for Default ACLs.
*/
/* Create the canon_ace lists. */
SMB_ACL_TYPE_ACCESS);
/* We must have *some* ACLS. */
-
+
if (count_canon_ace_list(file_ace) == 0) {
DEBUG(0,("get_nt_acl : No ACLs on file (%s) !\n", name));
goto done;
for (i = 0; i < num_aces; i++) {
if (sid_equal(&nt_ace_list[i].trustee, &owner_sid)) {
add_or_replace_ace(nt_ace_list, &num_aces,
- &orig_owner_sid,
- nt_ace_list[i].type,
- nt_ace_list[i].access_mask,
+ &orig_owner_sid,
+ nt_ace_list[i].type,
+ nt_ace_list[i].access_mask,
nt_ace_list[i].flags);
break;
}
1) If we have root privileges, then it will just work.
2) If we have SeTakeOwnershipPrivilege we can change the user to the current user.
- 3) If we have SeRestorePrivilege we can change the user to any other user.
+ 3) If we have SeRestorePrivilege we can change the user to any other user.
4) If we have write permission to the file and dos_filemodes is set
then allow chown to the currently authenticated user.
****************************************************************************/
/*
* If this is a simple 3 element ACL or no elements then it's a standard
- * UNIX permission set. Just use chmod...
+ * UNIX permission set. Just use chmod...
*/
if ((num_entries == 3) || (num_entries == 0))
/********************************************************************
Pull the NT ACL from a file on disk or the OpenEventlog() access
check. Caller is responsible for freeing the returned security
- descriptor via TALLOC_FREE(). This is designed for dealing with
+ descriptor via TALLOC_FREE(). This is designed for dealing with
user space access checks in smbd outside of the VFS. For example,
checking access rights in OpenEventlog().
-/*
+/*
Unix SMB/CIFS implementation.
process incoming packets - main loop
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Volker Lendecke 2005-2007
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../librpc/gen_ndr/srv_dfs.h"
#include "../librpc/gen_ndr/srv_dssetup.h"
#include "../librpc/gen_ndr/srv_echo.h"
}
/*
-These flags determine some of the permissions required to do an operation
+These flags determine some of the permissions required to do an operation
Note that I don't set NEED_WRITE on some write operations because they
are used by some brain-dead clients when printing, and I don't want to
#define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
#define DO_CHDIR (1<<6)
-/*
+/*
define a list of possible SMB messages and their corresponding
functions. Any message that has a NULL function is unimplemented -
please feel free to contribute implementations!
SCVAL(outbuf, smb_com, req->cmd);
SIVAL(outbuf,smb_rcls,0);
- SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
+ SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
SSVAL(outbuf,smb_flg2,
(SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
common_flags2);
/* 'printcap cache time = 0' disable the feature */
if ( printcap_cache_time != 0 )
- {
+ {
/* see if it's time to reload or if the clock has been set back */
- if ( (t >= last_printer_reload_time+printcap_cache_time)
- || (t-last_printer_reload_time < 0) )
+ if ( (t >= last_printer_reload_time+printcap_cache_time)
+ || (t-last_printer_reload_time < 0) )
{
DEBUG( 3,( "Printcap cache time expired.\n"));
reload_printers();
-/*
+/*
Unix SMB/CIFS implementation.
support for quotas
Copyright (C) Andrew Tridgell 1992-1998
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/*
+/*
* This is one of the most system dependent parts of Samba, and its
- * done a litle differently. Each system has its own way of doing
+ * done a litle differently. Each system has its own way of doing
* things :-(
*/
/*
* This code presumes that OSF1 will only
- * give out quota info when the real uid
+ * give out quota info when the real uid
* matches the effective uid. JRA.
*/
euser_id = geteuid();
return (True);
}
else
- return (False);
+ return (False);
}
/* If softlimit is zero, set it equal to hardlimit.
struct mntent *mnt;
SMB_DEV_T devno;
int found;
-
+
/* find the block device file */
-
+
if ( sys_stat(path, &S, false) == -1 ) {
return(False) ;
}
devno = S.st_ex_dev ;
-
+
fp = setmntent(MOUNTED,"r");
found = False ;
-
+
while ((mnt = getmntent(fp))) {
if ( sys_stat(mnt->mnt_dir, &S, false) == -1 )
continue ;
}
}
endmntent(fp) ;
-
+
if (!found) {
return(False);
}
if (r==-1)
return(False);
-
+
/* Use softlimit to determine disk space, except when it has been exceeded */
if (
(D.dqb_bsoftlimit && D.dqb_curblocks>=D.dqb_bsoftlimit) ||
{
return(False);
}
- else
+ else
{
*dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
*dsize = D.dqb_bsoftlimit;
DEBUG(5, ("quotactl for uid=%u: %s", euser_id, strerror(errno)));
return(False);
}
-
+
/* No quota for this user. */
if (F.d_blk_softlimit==0 && F.d_blk_hardlimit==0)
{
*dfree = 0;
*dsize = F.d_bcount;
}
- else
+ else
{
*dfree = (F.d_blk_softlimit - F.d_bcount);
*dsize = F.d_blk_softlimit ? F.d_blk_softlimit : F.d_blk_hardlimit;
#define dqb_curfiles dqb_curinodes
#define dqb_fhardlimit dqb_ihardlimit
#define dqb_fsoftlimit dqb_isoftlimit
-#ifdef _AIXVERSION_530
+#ifdef _AIXVERSION_530
#include <sys/statfs.h>
#include <sys/vmount.h>
#endif /* AIX 5.3 */
goto out;
}
- /*
+ /*
* gqr->status returns 0 if the rpc call fails, 1 if quotas exist, 2 if there is
* no quota set, and 3 if no permission to get the quota. If 0 or 3 return
* something sensible.
- */
+ */
switch (gqr.status) {
case 0:
/* for HPUX, real uid must be same as euid to execute quotactl for euid */
save_re_uid();
if (set_re_uid() != 0) return False;
-
+
r=quotactl(Q_GETQUOTA, dev_disk, euser_id, &D);
restore_re_uid();
-#else
+#else
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
{
/* FreeBSD patches from Marty Moll <martym@arbor.edu> */
struct statfs *mnts;
SMB_STRUCT_STAT st;
int mntsize, i;
-
+
if (sys_stat(path, &st, false) < 0)
return False;
devno = st.st_ex_dev;
if (i == mntsize)
return False;
#endif
-
+
become_root();
#if defined(__FreeBSD__) || defined(__DragonFly__)
unbecome_root();
}
#elif defined(AIX)
- /* AIX has both USER and GROUP quotas:
+ /* AIX has both USER and GROUP quotas:
Get the USER quota (ohnielse@fysik.dtu.dk) */
#ifdef _AIXVERSION_530
{
{
#endif /* AIX 5.3 */
save_re_uid();
- if (set_re_uid() != 0)
+ if (set_re_uid() != 0)
return False;
r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D);
restore_re_uid();
if (r)
{
- if (errno == EDQUOT)
+ if (errno == EDQUOT)
{
- *dfree =0;
- *dsize =D.dqb_curblocks;
- return (True);
+ *dfree =0;
+ *dsize =D.dqb_curblocks;
+ return (True);
}
else return(False);
}
Almost certainly "include"s require attention: see SUNOS5.
In the main code above, arrange for it to be called: see SUNOS5.
Test!
-
+
****************************************************************************/
/* "IFLIST"
*dsize = D.dqb_curblocks;
} else
*dfree = D.dqb_bsoftlimit - D.dqb_curblocks;
-
+
DEBUG(5,("disk_quotas for path \"%s\" returning bsize %.0f, dfree %.0f, dsize %.0f\n",
path,(double)*bsize,(double)*dfree,(double)*dsize));
id.uid = geteuid();
ZERO_STRUCT(D);
- r=sys_get_quota(path, SMB_USER_QUOTA_TYPE, id, &D);
+ r=sys_get_quota(path, SMB_USER_QUOTA_TYPE, id, &D);
/* Use softlimit to determine disk space, except when it has been exceeded */
*bsize = D.bsize;
}
return True;
-
+
try_group_quota:
id.gid = getegid();
ZERO_STRUCT(D);
- r=sys_get_quota(path, SMB_GROUP_QUOTA_TYPE, id, &D);
+ r=sys_get_quota(path, SMB_GROUP_QUOTA_TYPE, id, &D);
/* Use softlimit to determine disk space, except when it has been exceeded */
*bsize = D.bsize;
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
/****************************************************************************
Ensure we check the path in *exactly* the same way as W2K for a findfirst/findnext
SCVAL(outbuf,0,0x82);
SCVAL(outbuf,3,0);
- if (name_len(inbuf+4) > 50 ||
+ if (name_len(inbuf+4) > 50 ||
name_len(inbuf+4 + name_len(inbuf + 4)) > 50) {
DEBUG(0,("Invalid name length in session request\n"));
return;
name_type2));
if (name_type2 == 'R') {
- /* We are being asked for a pathworks session ---
+ /* We are being asked for a pathworks session ---
no thanks! */
SCVAL(outbuf, 0,0x83);
break;
sconn->nbt.got_session = true;
break;
- case 0x89: /* session keepalive request
+ case 0x89: /* session keepalive request
(some old clients produce this?) */
SCVAL(outbuf,0,SMBkeepalive);
SCVAL(outbuf,3,0);
p += 1; /* Allow for alignment */
switch (ioctl_code) {
- case IOCTL_QUERY_JOB_INFO:
+ case IOCTL_QUERY_JOB_INFO:
{
files_struct *fsp = file_fsp(
req, SVAL(req->vwv+0, 0));
double total_space, free_space;
/* we need to scale this to a number that DOS6 can handle. We
use floating point so we can handle large drives on systems
- that don't have 64 bit integers
+ that don't have 64 bit integers
we end up displaying a maximum of 2G to DOS systems
*/
SearchEmpty:
/* If we were called as SMBffirst with smb_search_id == NULL
- and no entries were found then return error and close dirptr
+ and no entries were found then return error and close dirptr
(X/Open spec) */
if (numentries == 0) {
FILE_SHARE_NONE, /* share_access */
FILE_OPEN, /* create_disposition*/
FILE_NON_DIRECTORY_FILE, /* create_options */
- /* file_attributes */
+ /* file_attributes */
posix_paths ? FILE_FLAG_POSIX_SEMANTICS|0777 :
FILE_ATTRIBUTE_NORMAL,
0, /* oplock_request */
}
/* XXXX the CIFS spec says that if bit0 of the flags2 field is set then
- the pattern matches against the long name, otherwise the short name
+ the pattern matches against the long name, otherwise the short name
We don't implement this yet XXXX
*/
#if defined(WITH_SENDFILE)
/*
- * We can only use sendfile on a non-chained packet
+ * We can only use sendfile on a non-chained packet
* but we can use on a non-oplocked file. tridge proved this
* on a train in Germany :-). JRA.
* reply_readbraw has already checked the length.
/*
* NB. Discovered by Menny Hamburger at Mainsoft. This is a core+
- * protocol request that predates the read/write lock concept.
+ * protocol request that predates the read/write lock concept.
* Thus instead of asking for a read lock here we need to ask
* for a write lock. JRA.
* Note that the requested lock size is unaffected by max_recv.
if (nwritten > 0) {
total_written += nwritten;
}
- }
+ }
TALLOC_FREE(buf);
SSVAL(req->outbuf,smb_vwv0,total_written);
status = do_unlock(smbd_messaging_context(),
fsp,
req->smbpid,
- (uint64_t)numtowrite,
+ (uint64_t)numtowrite,
(uint64_t)startpos,
WINDOWS_LOCK);
END_PROFILE(SMBwriteX);
return;
}
- if (numtowrite != req->unread_bytes) {
+ if (numtowrite != req->unread_bytes) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
END_PROFILE(SMBwriteX);
return;
*/
status = close_file(req, fsp, NORMAL_CLOSE);
- }
+ }
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
struct smb_filename *smb_fname_dst_tmp = NULL;
SMB_OFF_T ret=-1;
files_struct *fsp1,*fsp2;
- uint32 dosattrs;
+ uint32 dosattrs;
uint32 new_create_disposition;
NTSTATUS status;
fsp,
e->smbpid,
e->count,
- e->offset,
+ e->offset,
e->brltype,
WINDOWS_LOCK,
blocking_lock,
reply_outbuf(req, 0, 0);
- /*
+ /*
* Patch from Ray Frush <frush@engr.colostate.edu>
* Sometimes times are sent as zero - ignore them.
*/
for(ii=0;ii<j->referral_count;ii++) {
char* p;
char *path = NULL;
- struct dfs_StorageInfo* stor = &(dfs3->stores[ii]);
+ struct dfs_StorageInfo* stor = &(dfs3->stores[ii]);
struct referral* ref = &(j->referral_list[ii]);
path = talloc_strdup(mem_ctx, ref->alternate_path);
p->rng_fault_state = true;
return WERR_NOT_SUPPORTED;
}
-
-/*
+/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines for rpcecho
* Copyright (C) Tim Potter 2003
* Copyright (C) Jelmer Vernooij 2006
* Copyright (C) Gerald (Jerry) Carter 2007
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
{
DEBUG(10, ("_echo_AddOne\n"));
- *r->out.out_data = r->in.in_data + 1;
+ *r->out.out_data = r->in.in_data + 1;
}
/* Echo back an array of data */
{
DEBUG(10, ("_echo_EchoData\n"));
- if ( r->in.len == 0 ) {
+ if ( r->in.len == 0 ) {
r->out.out_data = NULL;
return;
}
r->out.out_data = TALLOC_ARRAY(p->mem_ctx, uint8, r->in.len);
memcpy( r->out.out_data, r->in.in_data, r->in.len );
- return;
+ return;
}
/* Sink an array of data */
DEBUG(10, ("_echo_SinkData\n"));
/* My that was some yummy data! */
- return;
+ return;
}
/* Source an array of data */
DEBUG(10, ("_echo_SourceData\n"));
if ( r->in.len == 0 ) {
- r->out.data = NULL;
+ r->out.data = NULL;
return;
}
r->out.data = TALLOC_ARRAY(p->mem_ctx, uint8, r->in.len );
- for (i = 0; i < r->in.len; i++ ) {
+ for (i = 0; i < r->in.len; i++ ) {
r->out.data[i] = i & 0xff;
}
-
- return;
+
+ return;
}
void _echo_TestCall(pipes_struct *p, struct echo_TestCall *r)
-/*
+/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997.
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
s.in.do_reboot = r->in.do_reboot;
s.in.reason = 0;
- /* thunk down to _winreg_InitiateSystemShutdownEx()
+ /* thunk down to _winreg_InitiateSystemShutdownEx()
(just returns a status) */
-
+
return _winreg_InitiateSystemShutdownEx( p, &s );
}
-/*
+/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1997,
* Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
* Copyright (C) Jeremy Allison 2001.
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
p->pipe_handles->count++;
*hnd = pol->pol_hnd;
-
+
DEBUG(4,("Opened policy hnd[%d] ", (int)p->pipe_handles->count));
dump_data(4, (uint8 *)hnd, sizeof(*hnd));
}
/* des_access is for the account here, not the policy
- * handle - so don't check against policy handle. */
+ * handle - so don't check against policy handle. */
/* Work out max allowed. */
map_max_allowed_access(p->server_info->ptok,
/*
* From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
- * on the policy handle. If it does, ask for
- * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
- * on the account sid. We don't check here so just use the latter. JRA.
- */
+ * on the policy handle. If it does, ask for
+ * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
+ * on the account sid. We don't check here so just use the latter. JRA.
+ */
status = access_check_object(psd, p->server_info->ptok,
NULL, 0,
* From the MS DOCs. We need
* LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
* and DELETE on the account sid.
- */
+ */
status = access_check_object(psd, p->server_info->ptok,
NULL, 0,
ret = pdb_getsampwnam(sampass, mach_acct);
unbecome_root();
- if (!ret) {
- DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
+ if (!ret) {
+ DEBUG(0,("get_md4pw: Workstation %s: no account in domain\n", mach_acct));
TALLOC_FREE(sampass);
return NT_STATUS_ACCESS_DENIED;
}
p->rng_fault_state = true;
return NT_STATUS_NOT_IMPLEMENTED;
}
-
p->rng_fault_state = true;
return WERR_NOT_SUPPORTED;
}
-
-/*
+/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
* Almost completely rewritten by (C) Jeremy Allison 2005 - 2010
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
}
/*******************************************************************
- Generate the next PDU to be returned from the data in p->rdata.
+ Generate the next PDU to be returned from the data in p->rdata.
Handle NTLMSSP.
********************************************************************/
DEBUG(10,("create_next_pdu_ntlmssp: adding sign/seal padding of %u\n",
ss_padding_len ));
/* If we're over filling the packet, we need to make space
- * for the padding at the end of the data. */
+ * for the padding at the end of the data. */
if (data_len + ss_padding_len > data_space_available) {
data_len -= SERVER_NDR_PADDING_SIZE;
}
}
/*******************************************************************
- Generate the next PDU to be returned from the data in p->rdata.
+ Generate the next PDU to be returned from the data in p->rdata.
Return an schannel authenticated fragment.
********************************************************************/
DEBUG(10,("create_next_pdu_schannel: adding sign/seal padding of %u\n",
ss_padding_len ));
/* If we're over filling the packet, we need to make space
- * for the padding at the end of the data. */
+ * for the padding at the end of the data. */
if (data_len + ss_padding_len > data_space_available) {
data_len -= SERVER_NDR_PADDING_SIZE;
}
}
/*******************************************************************
- Generate the next PDU to be returned from the data in p->rdata.
+ Generate the next PDU to be returned from the data in p->rdata.
No authentication done.
********************************************************************/
}
/*******************************************************************
- Generate the next PDU to be returned from the data in p->rdata.
+ Generate the next PDU to be returned from the data in p->rdata.
********************************************************************/
bool create_next_pdu(pipes_struct *p)
/* We must NEVER look at auth_info->auth_pad_len here,
* as old Samba client code gets it wrong and sends it
* as zero. JRA.
- */
+ */
if (auth_info.auth_type != DCERPC_AUTH_TYPE_NTLMSSP) {
DEBUG(0,("api_pipe_bind_auth3: incorrect auth type (%u).\n",
if (version != SMB_RPC_INTERFACE_VERSION) {
DEBUG(0,("Can't register rpc commands!\n"
"You tried to register a rpc module with SMB_RPC_INTERFACE_VERSION %d"
- ", while this version of samba uses version %d!\n",
+ ", while this version of samba uses version %d!\n",
version,SMB_RPC_INTERFACE_VERSION));
return NT_STATUS_OBJECT_TYPE_MISMATCH;
}
- /* TODO:
+ /* TODO:
*
* we still need to make sure that don't register the same commands twice!!!
- *
+ *
* --metze
*/
- /* We use a temporary variable because this call can fail and
+ /* We use a temporary variable because this call can fail and
rpc_lookup will still be valid afterwards. It could then succeed if
called again later */
rpc_lookup_size++;
prs_init_empty(&p->out_data.frag, p->mem_ctx, MARSHALL);
- /*
+ /*
* Marshall directly into the outgoing PDU space. We
* must do this as we need to set to the bind response
* header and are never sending more than one PDU here.
*/
if (p->hdr.auth_len) {
- /*
+ /*
* Decode the authentication verifier.
*/
prs_init_empty(&p->out_data.frag, p->mem_ctx, MARSHALL);
- /*
+ /*
* Marshall directly into the outgoing PDU space. We
* must do this as we need to set to the bind response
* header and are never sending more than one PDU here.
*/
if (p->hdr.auth_len != 0) {
- /*
+ /*
* Decode the authentication verifier.
*/
/*
* We need the full packet data + length (minus auth stuff) as well as the packet data + length
* after the RPC header.
- * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
+ * We need to pass in the full packet (minus auth len) to the NTLMSSP sign and check seal
* functions as NTLMv2 checks the rpc headers also.
* Both of these values include any auth_pad_len bytes.
*/
return False;
}
- data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
+ data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
RPC_HDR_AUTH_LEN - auth_len;
DEBUG(5,("data %d auth %d\n", data_len, auth_len));
tmp = tmp2;
}
- return;
+ return;
}
static bool api_rpcTNP(pipes_struct *p,
offset1 = prs_offset(&p->out_data.rdata);
- DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
+ DEBUG(6, ("api_rpc_cmds[%d].fn == %p\n",
fn_num, api_rpc_cmds[fn_num].fn));
/* do the actual command */
if(!api_rpc_cmds[fn_num].fn(p)) {
/* Check for buffer underflow in rpc parsing */
- if ((DEBUGLEVEL >= 10) &&
+ if ((DEBUGLEVEL >= 10) &&
(prs_offset(&p->in_data.data) != prs_data_size(&p->in_data.data))) {
size_t data_len = prs_data_size(&p->in_data.data) - prs_offset(&p->in_data.data);
char *data = (char *)SMB_MALLOC(data_len);
-/*
+/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-1998,
* Largely re-written : 2005
* Copyright (C) Jeremy Allison 1998 - 2005
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* Initialize the outgoing RPC data buffer.
* we will use this as the raw data area for replying to rpc requests.
- */
+ */
if(!prs_init(&o_data->rdata, 128, p->mem_ctx, MARSHALL)) {
DEBUG(0,("pipe_init_outgoing_data: malloc fail.\n"));
return False;
/*
* Initialize the outgoing RPC data buffer with no memory.
- */
+ */
prs_init_empty(&p->out_data.rdata, p->mem_ctx, MARSHALL);
p->syntax = *syntax;
* spoolsv.exe when the response to a GETPRINTERDRIVER2 RPC
* will not fit in the initial buffer of size 0x1068 --jerry 22/01/2002
*/
-
+
if(prs_offset(&p->in_data.data) + data_len > MAX_RPC_DATA_SIZE) {
DEBUG(0,("process_request_pdu: rpc data buffer too large (%u) + (%u)\n",
(unsigned int)prs_data_size(&p->in_data.data), (unsigned int)data_len ));
* size as the current offset.
*/
- if(!prs_set_buffer_size(&p->in_data.data, prs_offset(&p->in_data.data))) {
+ if(!prs_set_buffer_size(&p->in_data.data, prs_offset(&p->in_data.data))) {
DEBUG(0,("process_request_pdu: Call to prs_set_buffer_size failed!\n"));
set_incoming_fault(p);
return False;
prs_init_empty( &rpc_in, p->mem_ctx, UNMARSHALL);
/*
- * Ensure we're using the corrent endianness for both the
+ * Ensure we're using the corrent endianness for both the
* RPC header flags and the raw data we will be reading from.
*/
*/
/*
- * If pdu_needed_len is zero this is a new pdu.
+ * If pdu_needed_len is zero this is a new pdu.
* Unmarshall the header so we know how much more
* data we need, then loop again.
*/
data_left -= data_used;
data += data_used;
- }
+ }
return n;
}
if (!p) {
DEBUG(0,("read_from_pipe: pipe not open\n"));
- return -1;
+ return -1;
}
DEBUG(6,(" name: %s len: %u\n",
*/
/*
- * This condition should result in the connection being closed.
+ * This condition should result in the connection being closed.
* Netapp filers seem to set it to 0xffff which results in domain
* authentications failing. Just ignore it so things work.
*/
}
/*
- * Determine if there is still data to send in the
+ * Determine if there is still data to send in the
* pipe PDU buffer. Always send this first. Never
* send more than is left in the current PDU. The
* client should send a new read request for a new
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/auth/libcli_auth.h"
#include "../librpc/gen_ndr/srv_samr.h"
/* check that the SID exists in our domain. */
if (ret == False) {
- return NT_STATUS_NO_SUCH_USER;
+ return NT_STATUS_NO_SUCH_USER;
}
/* If we did the rid admins hack above, allow access. */
case 13:
status = query_dom_info_13(p->mem_ctx, &dom_info->info13);
break;
- default:
- return NT_STATUS_INVALID_INFO_CLASS;
+ default:
+ return NT_STATUS_INVALID_INFO_CLASS;
}
if (!NT_STATUS_IS_OK(status)) {
/* write the change out */
if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
return status;
- }
+ }
return NT_STATUS_OK;
}
&len,
CH_UTF16)) {
return False;
- }
+ }
if (!pdb_set_plaintext_passwd (pwd, plaintext_buf)) {
return False;
status = pdb_update_sam_account(pwd);
if (!NT_STATUS_IS_OK(status)) {
return status;
- }
+ }
return NT_STATUS_OK;
}
/* write the change out */
if(!NT_STATUS_IS_OK(status = pdb_update_sam_account(pwd))) {
return status;
- }
+ }
/*
* We need to "pdb_update_sam_account" before the unix primary group
if (!ret) {
TALLOC_FREE(pwd);
return NT_STATUS_NO_SUCH_USER;
- }
+ }
/* ================ BEGIN Privilege BLOCK ================ */
switch (r->in.level) {
case 1:
status = set_dom_info_1(p->mem_ctx, &r->in.info->info1);
- break;
+ break;
case 3:
status = set_dom_info_3(p->mem_ctx, &r->in.info->info3);
break;
messaging_deregister(smbd_messaging_context(),
MSG_PRINTER_NOTIFY2, NULL);
- /* Tell the connections db we're no longer interested in
+ /* Tell the connections db we're no longer interested in
* printer notify messages. */
register_message_flags(false, FLAG_MSG_PRINT_NOTIFY);
}
- if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
+ if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
*type = REG_SZ;
data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
DEBUG(0,("%s: invalid level=%d\n", fn,
r->in.info_ctr->level));
break;
- }
+ }
done:
/*
* See the section "Dynamically Typed Query Parameters"
- * in MS-RPRN.
- */
+ * in MS-RPRN.
+ */
if (r->out.data && val->data && val->data->data &&
val->data_length && r->in.data_offered) {
return WERR_BADFID;
status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
- if (!W_ERROR_IS_OK(status))
+ if (!W_ERROR_IS_OK(status))
goto done;
}
return WERR_BADFID;
status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
- if (!W_ERROR_IS_OK(status))
+ if (!W_ERROR_IS_OK(status))
goto done;
}
return WERR_BADFID;
status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
- if (!W_ERROR_IS_OK(status))
+ if (!W_ERROR_IS_OK(status))
goto done;
}
const char *sharepath, const char *fname,
void *private_data )
{
- struct file_enum_count *fenum =
- (struct file_enum_count *)private_data;
+ struct file_enum_count *fenum =
+ (struct file_enum_count *)private_data;
struct srvsvc_NetFileInfo3 *f;
int i = fenum->ctr3->count;
{
char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
struct srvsvc_NetFileClose *r =
- (struct srvsvc_NetFileClose *)private_data;
+ (struct srvsvc_NetFileClose *)private_data;
uint32_t fid = (((uint32_t)(procid_to_pid(&e->pid))<<16) | e->share_file_id);
if (fid != r->in.fid) {
p->rng_fault_state = True;
return WERR_NOT_SUPPORTED;
}
-
p->rng_fault_state = True;
return WERR_NOT_SUPPORTED;
}
-
int ret;
bool can_shutdown;
- shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
+ shutdown_script = talloc_strdup(p->mem_ctx, lp_shutdown_script());
if (!shutdown_script) {
return WERR_NOMEM;
}
-/*
+/*
* Unix SMB/CIFS implementation.
* RPC Pipe client / server routines
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/********************************************************************
********************************************************************/
-WERROR _wkssvc_NetrWorkstationStatisticsGet(pipes_struct *p, struct wkssvc_NetrWorkstationStatisticsGet *r)
+WERROR _wkssvc_NetrWorkstationStatisticsGet(pipes_struct *p, struct wkssvc_NetrWorkstationStatisticsGet *r)
{
/* FIXME: Add implementation code here */
p->rng_fault_state = True;
p->rng_fault_state = True;
return WERR_NOT_SUPPORTED;
}
-
-/*
+/*
Unix SMB/CIFS implementation.
SMB Transport encryption (sealing) code - server code.
Copyright (C) Jeremy Allison 2007.
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/auth/spnego.h"
#include "ntlmssp.h"
/*
* We're accessing the krb5.keytab file here.
- * ensure we have permissions to do so.
- */
+ * ensure we have permissions to do so.
+ */
become_root();
ret = gss_acquire_cred(&min,
-/*
+/*
Unix SMB/CIFS implementation.
uid/user handling
Copyright (C) Tim Potter 2000
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
extern struct current_user current_user;
{
/* Check for dodgy uid values */
- if (uid == (uid_t)-1 ||
+ if (uid == (uid_t)-1 ||
((sizeof(uid_t) == 2) && (uid == (uid_t)65535))) {
if (!become_uid_done) {
DEBUG(1,("WARNING: using uid %d is a security risk\n",
{
/* Check for dodgy gid values */
- if (gid == (gid_t)-1 || ((sizeof(gid_t) == 2) &&
+ if (gid == (gid_t)-1 || ((sizeof(gid_t) == 2) &&
(gid == (gid_t)65535))) {
if (!become_gid_done) {
DEBUG(1,("WARNING: using gid %d is a security risk\n",
- (int)gid));
+ (int)gid));
become_gid_done = true;
}
}
-
+
/* Set effective group id */
set_effective_gid(gid);
ctx_p->ut.uid = geteuid();
ctx_p->ut.gid = getegid();
- DEBUG(3, ("push_sec_ctx(%u, %u) : sec_ctx_stack_ndx = %d\n",
- (unsigned int)ctx_p->ut.uid, (unsigned int)ctx_p->ut.gid, sec_ctx_stack_ndx ));
+ DEBUG(3, ("push_sec_ctx(%u, %u) : sec_ctx_stack_ndx = %d\n",
+ (unsigned int)ctx_p->ut.uid, (unsigned int)ctx_p->ut.gid, sec_ctx_stack_ndx ));
ctx_p->token = dup_nt_token(NULL,
sec_ctx_stack[sec_ctx_stack_ndx-1].token);
void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN *token)
{
struct sec_ctx *ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];
-
+
/* Set the security context */
- DEBUG(3, ("setting sec ctx (%u, %u) - sec_ctx_stack_ndx = %d\n",
+ DEBUG(3, ("setting sec ctx (%u, %u) - sec_ctx_stack_ndx = %d\n",
(unsigned int)uid, (unsigned int)gid, sec_ctx_stack_ndx));
debug_nt_user_token(DBGC_CLASS, 5, token);
}
TALLOC_FREE(ctx_p->token);
-
+
if (ngroups) {
ctx_p->ut.groups = (gid_t *)memdup(groups,
sizeof(gid_t) * ngroups);
current_user.ut.groups = prev_ctx_p->ut.groups;
current_user.nt_user_token = prev_ctx_p->token;
- DEBUG(3, ("pop_sec_ctx (%u, %u) - sec_ctx_stack_ndx = %d\n",
+ DEBUG(3, ("pop_sec_ctx (%u, %u) - sec_ctx_stack_ndx = %d\n",
(unsigned int)geteuid(), (unsigned int)getegid(), sec_ctx_stack_ndx));
return True;
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
static_decl_rpc;
Using a timer for this prevents a flood of traversals when a large
number of clients disconnect at the same time (perhaps due to a
- network outage).
+ network outage).
*/
static void cleanup_timeout_fn(struct event_context *event_ctx,
DEBUGLEVEL = oldlevel;
dump_core();
- } else {
+ } else {
DEBUG(3,("Server exit (%s)\n",
(reason ? reason : "normal exit")));
if (am_parent) {
DEBUG(2,("uid=%d gid=%d euid=%d egid=%d\n",
(int)getuid(),(int)getgid(),(int)geteuid(),(int)getegid()));
- /* Output the build options to the debug log */
+ /* Output the build options to the debug log */
build_options(False);
if (sizeof(uint16) < 2 || sizeof(uint32) < 4) {
exit(1);
if (!reload_services(False))
- return(-1);
+ return(-1);
init_structs();
exit(1);
}
- /* only start the background queue daemon if we are
+ /* only start the background queue daemon if we are
running as a daemon -- bad things will happen if
- smbd is launched via inetd and we fork a copy of
+ smbd is launched via inetd and we fork a copy of
ourselves here */
if (is_daemon && !interactive
-/*
+/*
Unix SMB/CIFS implementation.
service (connection) opening and closing
Copyright (C) Andrew Tridgell 1992-1998
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
extern userdom_struct current_user_info;
conn->lastused_count++;
snum = SNUM(conn);
-
+
if (do_chdir &&
vfs_ChDir(conn,conn->connectpath) != 0 &&
vfs_ChDir(conn,conn->origpath) != 0) {
last_conn = conn;
last_flags = flags;
-
+
/* Obey the client case sensitivity requests - only for clients that support it. */
switch (lp_casesensitive(snum)) {
case Auto:
if (!lp_add_home(service, iHomeService, username, homedir)) {
return -1;
}
-
+
return lp_servicenumber(service);
}
char *pdefservice = lp_defaultservice();
if (pdefservice && *pdefservice && !strequal(pdefservice,service) && !strstr_m(service,"..")) {
/*
- * We need to do a local copy here as lp_defaultservice()
+ * We need to do a local copy here as lp_defaultservice()
* returns one of the rotating lp_string buffers that
* could get overwritten by the recursive find_service() call
* below. Fix from Josef Hinteregger <joehtg@joehtg.co.at>.
/****************************************************************************
- do some basic sainity checks on the share.
+ do some basic sainity checks on the share.
This function modifies dev, ecode.
****************************************************************************/
-static NTSTATUS share_sanity_checks(int snum, fstring dev)
+static NTSTATUS share_sanity_checks(int snum, fstring dev)
{
-
- if (!lp_snum_ok(snum) ||
- !check_access(smbd_server_fd(),
- lp_hostsallow(snum), lp_hostsdeny(snum))) {
+
+ if (!lp_snum_ok(snum) ||
+ !check_access(smbd_server_fd(),
+ lp_hostsallow(snum), lp_hostsdeny(snum))) {
return NT_STATUS_ACCESS_DENIED;
}
}
/*
- * Go through lookup_name etc to find the force'd group.
+ * Go through lookup_name etc to find the force'd group.
*
* Create a new token from src_token, replacing the primary group sid with the
* one found.
add_session_user(sconn, conn->server_info->unix_name);
safe_strcpy(conn->client_address,
- client_addr(get_client_fd(),addr,sizeof(addr)),
+ client_addr(get_client_fd(),addr,sizeof(addr)),
sizeof(conn->client_address)-1);
conn->num_files_open = 0;
conn->lastused = conn->lastused_count = time(NULL);
/*
* We need to cache this gid, to use within
- * change_to_user() separately from the conn->server_info
- * struct. We only use conn->server_info directly if
- * "force_user" was set.
- */
+ * change_to_user() separately from the conn->server_info
+ * struct. We only use conn->server_info directly if
+ * "force_user" was set.
+ */
conn->force_group_gid = conn->server_info->utok.gid;
}
/****************************************************************************
Make a connection to a service.
*
- * @param service
+ * @param service
****************************************************************************/
connection_struct *make_connection(struct smbd_server_connection *sconn,
"created at session setup time\n"));
return make_connection_snum(sconn,
vuser->homes_snum,
- vuser, no_pw,
+ vuser, no_pw,
dev, status);
} else {
/* Security = share. Try with
current_user_info.smb_name);
map_username(sconn, unix_username);
snum = find_service(unix_username);
- }
+ }
if (snum != -1) {
DEBUG(5, ("making a connection to 'homes' "
"service %s based on "
"created at session setup time\n", service_in));
return make_connection_snum(sconn,
vuser->homes_snum,
- vuser, no_pw,
+ vuser, no_pw,
dev, status);
}
-
+
fstrcpy(service, service_in);
strlower_m(service);
/* Handle non-Dfs clients attempting connections to msdfs proxy */
if (lp_host_msdfs() && (*lp_msdfs_proxy(snum) != '\0')) {
DEBUG(3, ("refusing connection to dfs proxy share '%s' "
- "(pointing to %s)\n",
+ "(pointing to %s)\n",
service, lp_msdfs_proxy(snum)));
*status = NT_STATUS_BAD_NETWORK_NAME;
return NULL;
conn->client_address,
lp_servicename(SNUM(conn))));
- /* Call VFS disconnect hook */
+ /* Call VFS disconnect hook */
SMB_VFS_DISCONNECT(conn);
yield_connection(conn, lp_servicename(SNUM(conn)));
vfs_ChDir(conn, "/");
/* execute any "postexec = " line */
- if (*lp_postexec(SNUM(conn)) &&
+ if (*lp_postexec(SNUM(conn)) &&
change_to_user(conn, vuid)) {
char *cmd = talloc_sub_advanced(talloc_tos(),
lp_servicename(SNUM(conn)),
-/*
+/*
* Unix SMB/CIFS implementation.
* Service Control API Implementation
- *
+ *
* Copyright (C) Marcin Krzysztof Porwit 2005.
* Largely Rewritten by:
* Copyright (C) Gerald (Jerry) Carter 2005.
- *
+ *
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
- *
+ *
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
wresult = regkey_open_internal( NULL, &key, path, token,
REG_KEY_READ );
if ( !W_ERROR_IS_OK(wresult) ) {
- DEBUG(0,("svcctl_lookup_dispname: key lookup failed! [%s] (%s)\n",
+ DEBUG(0,("svcctl_lookup_dispname: key lookup failed! [%s] (%s)\n",
path, win_errstr(wresult)));
SAFE_FREE(path);
goto fail;
wresult = regkey_open_internal( NULL, &key, path, token,
REG_KEY_READ );
if ( !W_ERROR_IS_OK(wresult) ) {
- DEBUG(0,("svcctl_lookup_description: key lookup failed! [%s] (%s)\n",
+ DEBUG(0,("svcctl_lookup_description: key lookup failed! [%s] (%s)\n",
path, win_errstr(wresult)));
SAFE_FREE(path);
return NULL;
-/*
+/*
Unix SMB/CIFS implementation.
session handling for utmp and PAM
Copyright (C) tridge@samba.org 2001
Copyright (C) abartlet@samba.org 2001
- Copyright (C) Gerald (Jerry) Carter 2006
-
+ Copyright (C) Gerald (Jerry) Carter 2006
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
/********************************************************************
called when a session is created
memcpy(&sessionid, rec->value.dptr, sizeof(sessionid));
if (lp_utmp()) {
- sys_utmp_yield(sessionid.username, sessionid.hostname,
+ sys_utmp_yield(sessionid.username, sessionid.hostname,
sessionid.ip_addr_str,
sessionid.id_str, sessionid.id_num);
}
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/auth/spnego.h"
#include "ntlmssp.h"
} else if (lp_security() != SEC_SHARE) {
/*
* In share level we should ignore any passwords, so
- * only read them if we're not.
- */
+ * only read them if we're not.
+ */
char *pass = NULL;
bool unic= smb_flag2 & FLAGS2_UNICODE_STRINGS;
-/*
+/*
Unix SMB/CIFS implementation.
Check access based on valid users, read list and friends
Copyright (C) Volker Lendecke 2005
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
/*
* No prefix means direct username
* result that might be interpreted in a wrong way. */
smb_panic("substitutions failed");
}
-
+
/* check to see is we already have a SID */
if ( string_to_sid( &sid, name ) ) {
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
/***********************************************************
"signing negotiated = %u, mandatory_signing = %u.\n",
negotiated, mandatory));
}
-
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
static struct tevent_req *smbd_smb2_oplock_break_send(TALLOC_CTX *mem_ctx,
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req,
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
static struct tevent_req *smbd_smb2_flush_send(TALLOC_CTX *mem_ctx,
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req)
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
static struct tevent_req *smbd_smb2_ioctl_send(TALLOC_CTX *mem_ctx,
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
NTSTATUS smbd_smb2_request_process_keepalive(struct smbd_smb2_request *req)
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
struct smbd_smb2_lock_element {
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
/*
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
static struct tevent_req *smbd_smb2_notify_send(TALLOC_CTX *mem_ctx,
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
#include "../lib/tsocket/tsocket.h"
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
#include "../libcli/auth/spnego.h"
#include "ntlmssp.h"
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx,
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
#include "../lib/crypto/crypto.h"
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/smb/smb_common.h"
static struct tevent_req *smbd_smb2_write_send(TALLOC_CTX *mem_ctx,
-/*
+/*
Unix SMB/CIFS implementation.
server specific string routines
Copyright (C) Andrew Tridgell 2001
Copyright (C) Andrew Bartlett <abartlet@samba.org> 2003
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
/* Make sure we can't write a string past the end of the buffer */
-/*
+/*
Unix SMB/CIFS implementation.
VFS API's statvfs abstraction
Copyright (C) Alexander Bokovoy 2005
Copyright (C) Steve French 2005
Copyright (C) James Peach 2006
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
}
#endif
-/*
+/*
sys_statvfs() is an abstraction layer over system-dependent statvfs()/statfs()
for particular POSIX systems. Due to controversy of what is considered more important
between LSB and FreeBSD/POSIX.1 (IEEE Std 1003.1-2001) we need to abstract the interface
#include "includes.h"
#include "version.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/auth/libcli_auth.h"
#define DIR_ENTRY_SAFETY_MARGIN 4096
DEBUG(3,("call_trans2findnext: dirhandle = %d, max_data_bytes = %d, maxentries = %d, \
close_after_request=%d, close_if_end = %d requires_resume_key = %d \
resume_key = %d resume name = %s continue=%d level = %d\n",
- dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
+ dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
requires_resume_key, resume_key,
resume_name ? resume_name : "(NULL)", continue_bit, info_level));
for (i=0;(i<(int)maxentries) && !finished && !out_of_space ;i++) {
bool got_exact_match = False;
- /* this is a heuristic to avoid seeking the dirptr except when
+ /* this is a heuristic to avoid seeking the dirptr except when
absolutely necessary. It allows for a filename of about 40 chars */
if (space_remaining < DIRLEN_GUESS && numentries > 0) {
out_of_space = True;
case SMB_INFO_VOLUME:
/* Return volume name */
- /*
+ /*
* Add volume serial number - hash of a combination of
* the called hostname and the service name.
*/
SIVAL(pdata,0,len);
break;
- case SMB_QUERY_FS_VOLUME_INFO:
+ case SMB_QUERY_FS_VOLUME_INFO:
case SMB_FS_VOLUME_INFORMATION:
- /*
+ /*
* Add volume serial number - hash of a combination of
* the called hostname and the service name.
*/
- SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
+ SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^
(str_checksum(get_local_machine_name())<<16));
/* Max label len is 32 characters. */
#ifdef HAVE_SYS_QUOTAS
case SMB_FS_QUOTA_INFORMATION:
- /*
+ /*
* what we have to send --metze:
*
* Unknown1: 24 NULL bytes
* Unknown3: 6 NULL bytes
*
* 48 bytes total
- *
+ *
* details for Quota Flags:
- *
+ *
* 0x0020 Log Limit: log if the user exceeds his Hard Quota
* 0x0010 Log Warn: log if the user exceeds his Soft Quota
* 0x0002 Deny Disk: deny disk access when the user exceeds his Hard Quota
SSVAL(pdata,0,CIFS_UNIX_MAJOR_VERSION);
SSVAL(pdata,2,CIFS_UNIX_MINOR_VERSION);
- /* We have POSIX ACLs, pathname, encryption,
+ /* We have POSIX ACLs, pathname, encryption,
* large read/write, and locking capability. */
SBIG_UINT(pdata,4,((uint64_t)(
i < conn->server_info->ptok->num_sids; ++i) {
sid_bytes += ndr_size_dom_sid(
&conn->server_info->ptok->user_sids[i],
- NULL,
+ NULL,
0);
}
}
/* note: normaly there're 48 bytes,
- * but we didn't use the last 6 bytes for now
- * --metze
+ * but we didn't use the last 6 bytes for now
+ * --metze
*/
fsp = file_fsp(req, SVAL(params,0));
break;
}
- /*
- * sending this reply works fine,
- * but I'm not sure it's the same
+ /*
+ * sending this reply works fine,
+ * but I'm not sure it's the same
* like windows do...
* --metze
*/
params = *pparams;
SSVAL(params,0,0);
data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
- *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
+ *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
if (*ppdata == NULL ) {
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
data_size = max_data_bytes + DIR_ENTRY_SAFETY_MARGIN;
- *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
+ *ppdata = (char *)SMB_REALLOC(*ppdata, data_size);
if (*ppdata == NULL) {
return NT_STATUS_NO_MEMORY;
}
if (setting_write_time) {
/*
* This was a Windows setfileinfo on an open file.
- * NT does this a lot. We also need to
- * set the time here, as it can be read by
+ * NT does this a lot. We also need to
+ * set the time here, as it can be read by
* FindFirst/FindNext and with the patch for bug #2045
* in smbd/fileio.c it ensures that this timestamp is
* kept sticky even after a write. We save the request
return NT_STATUS_INVALID_PARAMETER;
}
- if (!lp_blocking_locks(SNUM(conn))) {
+ if (!lp_blocking_locks(SNUM(conn))) {
blocking_lock = False;
}
}
/* If any of the other "set" calls fail we
- * don't want to end up with a half-constructed mknod.
- */
+ * don't want to end up with a half-constructed mknod.
+ */
if (lp_inherit_perms(SNUM(conn))) {
char *parent;
struct smb_filename *smb_fname_tmp = NULL;
/*
* The only valid use of this is to create character and block
- * devices, and named pipes. This is deprecated (IMHO) and
+ * devices, and named pipes. This is deprecated (IMHO) and
* a new info level should be used for mknod. JRA.
*/
size = get_file_size_stat(&sbuf);
ft.atime = sbuf.st_ex_atime;
ft.mtime = sbuf.st_ex_mtime;
- /*
- * We continue here as we might want to change the
+ /*
+ * We continue here as we might want to change the
* owner uid/gid.
*/
delete_on_fail = True;
}
info_level_return = SVAL(pdata,16);
-
+
if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
*pdata_return_size = 12 + SMB_FILE_UNIX_BASIC_SIZE;
} else if (info_level_return == SMB_QUERY_FILE_UNIX_INFO2) {
}
info_level_return = SVAL(pdata,16);
-
+
/* Allocate the correct return size. */
if (info_level_return == SMB_QUERY_FILE_UNIX_BASIC) {
case SMB_SET_FILE_DISPOSITION_INFO: /* Set delete on close for open file. */
{
#if 0
- /* JRA - We used to just ignore this on a path ?
+ /* JRA - We used to just ignore this on a path ?
* Shouldn't this be invalid level on a pathname
* based call ?
*/
break;
}
- /* From tridge Samba4 :
+ /* From tridge Samba4 :
* MODE_INFORMATION in setfileinfo (I have no
* idea what "mode information" on a file is - it takes a value of 0,
* 2, 4 or 6. What could it be?).
}
/****************************************************************************
- Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
+ Reply to a TRANS2_FINDNOTIFYNEXT (continue monitoring a directory for
changes). Currently this does nothing.
****************************************************************************/
unsigned int max_data_bytes)
{
char *params = *pparams;
- char *pathname = NULL;
+ char *pathname = NULL;
int reply_size = 0;
int max_referral_level;
NTSTATUS status = NT_STATUS_OK;
DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
- /* We never give out valid handles for a
- findnotifyfirst - so any dptr_num is ok here.
+ /* We never give out valid handles for a
+ findnotifyfirst - so any dptr_num is ok here.
Just ignore it. */
reply_outbuf(req, 0, 0);
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBtrans2);
return;
- }
+ }
memcpy(state->param,smb_base(req->inbuf)+psoff,pscnt);
}
-/*
+/*
Unix SMB/CIFS implementation.
uid/user handling
Copyright (C) Andrew Tridgell 1992-1998
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
/* what user is current? */
extern struct current_user current_user;
}
#ifdef AIX
- /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before
+ /* MWW: From AIX FAQ patch to WU-ftpd: call initgroups before
setting IDs */
initgroups(pass->pw_name, pass->pw_gid);
#endif
DEBUG(4,("change_to_user: Skipping user change - already "
"user\n"));
return(True);
- } else if ((current_user.conn == conn) &&
+ } else if ((current_user.conn == conn) &&
(vuser != NULL) && (current_user.vuid == vuid) &&
(current_user.ut.uid == vuser->server_info->utok.uid)) {
DEBUG(4,("change_to_user: Skipping user change - already "
-/*
+/*
Unix SMB/CIFS implementation.
utmp routines
Copyright (C) T.D.Lee@durham.ac.uk 1999
Heavily modified by Andrew Bartlett and Tridge, April 2001
-
+
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
FreeBSD:
No "putut*()" type of interface.
- No "ut_type" and associated defines.
+ No "ut_type" and associated defines.
Write files directly. Alternatively use its login(3)/logout(3).
SunOS 4:
Not tested. Resembles FreeBSD, but no login()/logout().
if (! claim) {
/*
- * BSD-like systems:
+ * BSD-like systems:
* may use empty ut_name to distinguish a logout record.
*
* May need "if defined(SUNOS4)" etc. around some of these,
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_VFS
{
struct vfs_init_function_entry *entry = backends;
- if ((version != SMB_VFS_INTERFACE_VERSION)) {
+ if ((version != SMB_VFS_INTERFACE_VERSION)) {
DEBUG(0, ("Failed to register vfs module.\n"
"The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
"current SMB_VFS_INTERFACE_VERSION is %d.\n"
- "Please recompile against the current Samba Version!\n",
+ "Please recompile against the current Samba Version!\n",
version, SMB_VFS_INTERFACE_VERSION));
return NT_STATUS_OBJECT_TYPE_MISMATCH;
- }
+ }
if (!name || !name[0]) {
DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
LIB_EVENTLOG_OBJ = lib/eventlog/eventlog.o
-RPC_LSA_OBJ = rpc_server/srv_lsa_nt.o ../librpc/gen_ndr/srv_lsa.o
+RPC_LSA_OBJ = ../fileserver/rpc_server/srv_lsa_nt.o ../librpc/gen_ndr/srv_lsa.o
-RPC_NETLOG_OBJ = rpc_server/srv_netlog_nt.o \
+RPC_NETLOG_OBJ = ../fileserver/rpc_server/srv_netlog_nt.o \
../librpc/gen_ndr/srv_netlogon.o
-RPC_SAMR_OBJ = rpc_server/srv_samr_nt.o \
- rpc_server/srv_samr_util.o \
+RPC_SAMR_OBJ = ../fileserver/rpc_server/srv_samr_nt.o \
+ ../fileserver/rpc_server/srv_samr_util.o \
../librpc/gen_ndr/srv_samr.o
-RPC_INITSHUTDOWN_OBJ = ../librpc/gen_ndr/srv_initshutdown.o rpc_server/srv_initshutdown_nt.o
+RPC_INITSHUTDOWN_OBJ = ../librpc/gen_ndr/srv_initshutdown.o ../fileserver/rpc_server/srv_initshutdown_nt.o
-RPC_REG_OBJ = rpc_server/srv_winreg_nt.o \
+RPC_REG_OBJ = ../fileserver/rpc_server/srv_winreg_nt.o \
../librpc/gen_ndr/srv_winreg.o
-RPC_DSSETUP_OBJ = rpc_server/srv_dssetup_nt.o ../librpc/gen_ndr/srv_dssetup.o
+RPC_DSSETUP_OBJ = ../fileserver/rpc_server/srv_dssetup_nt.o ../librpc/gen_ndr/srv_dssetup.o
-RPC_SVC_OBJ = rpc_server/srv_srvsvc_nt.o \
+RPC_SVC_OBJ = ../fileserver/rpc_server/srv_srvsvc_nt.o \
../librpc/gen_ndr/srv_srvsvc.o
-RPC_WKS_OBJ = ../librpc/gen_ndr/srv_wkssvc.o rpc_server/srv_wkssvc_nt.o
+RPC_WKS_OBJ = ../librpc/gen_ndr/srv_wkssvc.o ../fileserver/rpc_server/srv_wkssvc_nt.o
-RPC_SVCCTL_OBJ = rpc_server/srv_svcctl_nt.o \
+RPC_SVCCTL_OBJ = ../fileserver/rpc_server/srv_svcctl_nt.o \
../librpc/gen_ndr/srv_svcctl.o \
- services/svc_spoolss.o services/svc_rcinit.o services/services_db.o \
- services/svc_netlogon.o services/svc_winreg.o \
- services/svc_wins.o
+ ../fileserver/services/svc_spoolss.o ../fileserver/services/svc_rcinit.o ../fileserver/services/services_db.o \
+ ../fileserver/services/svc_netlogon.o ../fileserver/services/svc_winreg.o \
+ ../fileserver/services/svc_wins.o
-RPC_NTSVCS_OBJ = rpc_server/srv_ntsvcs_nt.o \
+RPC_NTSVCS_OBJ = ../fileserver/rpc_server/srv_ntsvcs_nt.o \
../librpc/gen_ndr/srv_ntsvcs.o
-RPC_DFS_OBJ = ../librpc/gen_ndr/srv_dfs.o rpc_server/srv_dfs_nt.o
+RPC_DFS_OBJ = ../librpc/gen_ndr/srv_dfs.o ../fileserver/rpc_server/srv_dfs_nt.o
-RPC_SPOOLSS_OBJ = rpc_server/srv_spoolss_nt.o \
- rpc_server/srv_spoolss_util.o \
+RPC_SPOOLSS_OBJ = ../fileserver/rpc_server/srv_spoolss_nt.o \
+ ../fileserver/rpc_server/srv_spoolss_util.o \
../librpc/gen_ndr/srv_spoolss.o
-RPC_EVENTLOG_OBJ = rpc_server/srv_eventlog_nt.o \
+RPC_EVENTLOG_OBJ = ../fileserver/rpc_server/srv_eventlog_nt.o \
$(LIB_EVENTLOG_OBJ) ../librpc/gen_ndr/srv_eventlog.o
-RPC_PIPE_OBJ = rpc_server/srv_pipe_hnd.o \
- rpc_server/srv_pipe.o rpc_server/srv_lsa_hnd.o
+RPC_PIPE_OBJ = ../fileserver/rpc_server/srv_pipe_hnd.o \
+ ../fileserver/rpc_server/srv_pipe.o ../fileserver/rpc_server/srv_lsa_hnd.o
-RPC_ECHO_OBJ = rpc_server/srv_echo_nt.o ../librpc/gen_ndr/srv_echo.o
+RPC_ECHO_OBJ = ../fileserver/rpc_server/srv_echo_nt.o ../librpc/gen_ndr/srv_echo.o
RPC_SERVER_OBJ = @RPC_STATIC@ $(RPC_PIPE_OBJ)
RPC_CLIENT_OBJ = rpc_client/cli_pipe.o rpc_client/rpc_transport_np.o \
rpc_client/rpc_transport_sock.o rpc_client/rpc_transport_smbd.o
-LOCKING_OBJ = locking/locking.o locking/brlock.o locking/posix.o
+LOCKING_OBJ = ../fileserver/locking/locking.o ../fileserver/locking/brlock.o ../fileserver/locking/posix.o
PRIVILEGES_BASIC_OBJ = lib/privileges_basic.o
lib/account_pol.o $(PRIVILEGES_OBJ) \
lib/util_nscd.o lib/winbind_util.o $(SERVER_MUTEX_OBJ)
-DEVEL_HELP_WEIRD_OBJ = modules/weird.o
-CP850_OBJ = modules/CP850.o
-CP437_OBJ = modules/CP437.o
-CHARSET_MACOSXFS_OBJ = modules/charset_macosxfs.o
+DEVEL_HELP_WEIRD_OBJ = ../fileserver/modules/weird.o
+CP850_OBJ = ../fileserver/modules/CP850.o
+CP437_OBJ = ../fileserver/modules/CP437.o
+CHARSET_MACOSXFS_OBJ = ../fileserver/modules/charset_macosxfs.o
GROUPDB_OBJ = groupdb/mapping.o groupdb/mapping_tdb.o
$(LIB_OBJ) $(LIB_DUMMY_OBJ) \
$(POPT_LIB_OBJ)
-OPLOCK_OBJ = smbd/oplock.o smbd/oplock_irix.o smbd/oplock_linux.o \
- smbd/oplock_onefs.o
-
-NOTIFY_OBJ = smbd/notify.o smbd/notify_inotify.o smbd/notify_internal.o
-
-FNAME_UTIL_OBJ = smbd/filename_util.o
-
-VFS_DEFAULT_OBJ = modules/vfs_default.o
-VFS_AUDIT_OBJ = modules/vfs_audit.o
-VFS_EXTD_AUDIT_OBJ = modules/vfs_extd_audit.o
-VFS_FULL_AUDIT_OBJ = modules/vfs_full_audit.o
-VFS_FAKE_PERMS_OBJ = modules/vfs_fake_perms.o
-VFS_RECYCLE_OBJ = modules/vfs_recycle.o
-VFS_NETATALK_OBJ = modules/vfs_netatalk.o
-VFS_DEFAULT_QUOTA_OBJ = modules/vfs_default_quota.o
-VFS_READONLY_OBJ = modules/vfs_readonly.o modules/getdate.o
-VFS_CAP_OBJ = modules/vfs_cap.o
-VFS_EXPAND_MSDFS_OBJ = modules/vfs_expand_msdfs.o
-VFS_SHADOW_COPY_OBJ = modules/vfs_shadow_copy.o
-VFS_SHADOW_COPY2_OBJ = modules/vfs_shadow_copy2.o
-VFS_AFSACL_OBJ = modules/vfs_afsacl.o
-VFS_XATTR_TDB_OBJ = modules/vfs_xattr_tdb.o
-VFS_POSIXACL_OBJ = modules/vfs_posixacl.o
-VFS_AIXACL_OBJ = modules/vfs_aixacl.o modules/vfs_aixacl_util.o
-VFS_AIXACL2_OBJ = modules/vfs_aixacl2.o modules/vfs_aixacl_util.o modules/nfs4_acls.o
-VFS_SOLARISACL_OBJ = modules/vfs_solarisacl.o
-VFS_ZFSACL_OBJ = modules/vfs_zfsacl.o modules/nfs4_acls.o
-VFS_HPUXACL_OBJ = modules/vfs_hpuxacl.o
-VFS_IRIXACL_OBJ = modules/vfs_irixacl.o
-VFS_TRU64ACL_OBJ = modules/vfs_tru64acl.o
-VFS_CATIA_OBJ = modules/vfs_catia.o
-VFS_STREAMS_XATTR_OBJ = modules/vfs_streams_xattr.o
-VFS_STREAMS_DEPOT_OBJ = modules/vfs_streams_depot.o
-VFS_CACHEPRIME_OBJ = modules/vfs_cacheprime.o
-VFS_PREALLOC_OBJ = modules/vfs_prealloc.o
-VFS_COMMIT_OBJ = modules/vfs_commit.o
-VFS_GPFS_OBJ = modules/vfs_gpfs.o modules/gpfs.o modules/nfs4_acls.o
-VFS_NOTIFY_FAM_OBJ = modules/vfs_notify_fam.o
-VFS_READAHEAD_OBJ = modules/vfs_readahead.o
-VFS_TSMSM_OBJ = modules/vfs_tsmsm.o
-VFS_FILEID_OBJ = modules/vfs_fileid.o
-VFS_AIO_FORK_OBJ = modules/vfs_aio_fork.o
-VFS_PREOPEN_OBJ = modules/vfs_preopen.o
-VFS_SYNCOPS_OBJ = modules/vfs_syncops.o
-VFS_ACL_XATTR_OBJ = modules/vfs_acl_xattr.o
-VFS_ACL_TDB_OBJ = modules/vfs_acl_tdb.o
-VFS_SMB_TRAFFIC_ANALYZER_OBJ = modules/vfs_smb_traffic_analyzer.o
-VFS_ONEFS_OBJ = modules/vfs_onefs.o modules/onefs_acl.o modules/onefs_system.o \
- modules/onefs_open.o modules/onefs_streams.o modules/onefs_dir.o \
- modules/onefs_cbrl.o modules/onefs_notify.o modules/onefs_config.o
-VFS_ONEFS_SHADOW_COPY_OBJ = modules/vfs_onefs_shadow_copy.o modules/onefs_shadow_copy.o
-PERFCOUNT_ONEFS_OBJ = modules/perfcount_onefs.o
-PERFCOUNT_TEST_OBJ = modules/perfcount_test.o
-VFS_DIRSORT_OBJ = modules/vfs_dirsort.o
-VFS_SCANNEDONLY_OBJ = modules/vfs_scannedonly.o
-VFS_CROSSRENAME_OBJ = modules/vfs_crossrename.o
+OPLOCK_OBJ = ../fileserver/oplock.o ../fileserver/oplock_irix.o ../fileserver/oplock_linux.o \
+ ../fileserver/oplock_onefs.o
+
+NOTIFY_OBJ = ../fileserver/notify.o ../fileserver/notify_inotify.o ../fileserver/notify_internal.o
+
+FNAME_UTIL_OBJ = ../fileserver/filename_util.o
+
+VFS_DEFAULT_OBJ = ../fileserver/modules/vfs_default.o
+VFS_AUDIT_OBJ = ../fileserver/modules/vfs_audit.o
+VFS_EXTD_AUDIT_OBJ = ../fileserver/modules/vfs_extd_audit.o
+VFS_FULL_AUDIT_OBJ = ../fileserver/modules/vfs_full_audit.o
+VFS_FAKE_PERMS_OBJ = ../fileserver/modules/vfs_fake_perms.o
+VFS_RECYCLE_OBJ = ../fileserver/modules/vfs_recycle.o
+VFS_NETATALK_OBJ = ../fileserver/modules/vfs_netatalk.o
+VFS_DEFAULT_QUOTA_OBJ = ../fileserver/modules/vfs_default_quota.o
+VFS_READONLY_OBJ = ../fileserver/modules/vfs_readonly.o ../fileserver/modules/getdate.o
+VFS_CAP_OBJ = ../fileserver/modules/vfs_cap.o
+VFS_EXPAND_MSDFS_OBJ = ../fileserver/modules/vfs_expand_msdfs.o
+VFS_SHADOW_COPY_OBJ = ../fileserver/modules/vfs_shadow_copy.o
+VFS_SHADOW_COPY2_OBJ = ../fileserver/modules/vfs_shadow_copy2.o
+VFS_AFSACL_OBJ = ../fileserver/modules/vfs_afsacl.o
+VFS_XATTR_TDB_OBJ = ../fileserver/modules/vfs_xattr_tdb.o
+VFS_POSIXACL_OBJ = ../fileserver/modules/vfs_posixacl.o
+VFS_AIXACL_OBJ = ../fileserver/modules/vfs_aixacl.o ../fileserver/modules/vfs_aixacl_util.o
+VFS_AIXACL2_OBJ = ../fileserver/modules/vfs_aixacl2.o ../fileserver/modules/vfs_aixacl_util.o ../fileserver/modules/nfs4_acls.o
+VFS_SOLARISACL_OBJ = ../fileserver/modules/vfs_solarisacl.o
+VFS_ZFSACL_OBJ = ../fileserver/modules/vfs_zfsacl.o ../fileserver/modules/nfs4_acls.o
+VFS_HPUXACL_OBJ = ../fileserver/modules/vfs_hpuxacl.o
+VFS_IRIXACL_OBJ = ../fileserver/modules/vfs_irixacl.o
+VFS_TRU64ACL_OBJ = ../fileserver/modules/vfs_tru64acl.o
+VFS_CATIA_OBJ = ../fileserver/modules/vfs_catia.o
+VFS_STREAMS_XATTR_OBJ = ../fileserver/modules/vfs_streams_xattr.o
+VFS_STREAMS_DEPOT_OBJ = ../fileserver/modules/vfs_streams_depot.o
+VFS_CACHEPRIME_OBJ = ../fileserver/modules/vfs_cacheprime.o
+VFS_PREALLOC_OBJ = ../fileserver/modules/vfs_prealloc.o
+VFS_COMMIT_OBJ = ../fileserver/modules/vfs_commit.o
+VFS_GPFS_OBJ = ../fileserver/modules/vfs_gpfs.o ../fileserver/modules/gpfs.o ../fileserver/modules/nfs4_acls.o
+VFS_NOTIFY_FAM_OBJ = ../fileserver/modules/vfs_notify_fam.o
+VFS_READAHEAD_OBJ = ../fileserver/modules/vfs_readahead.o
+VFS_TSMSM_OBJ = ../fileserver/modules/vfs_tsmsm.o
+VFS_FILEID_OBJ = ../fileserver/modules/vfs_fileid.o
+VFS_AIO_FORK_OBJ = ../fileserver/modules/vfs_aio_fork.o
+VFS_PREOPEN_OBJ = ../fileserver/modules/vfs_preopen.o
+VFS_SYNCOPS_OBJ = ../fileserver/modules/vfs_syncops.o
+VFS_ACL_XATTR_OBJ = ../fileserver/modules/vfs_acl_xattr.o
+VFS_ACL_TDB_OBJ = ../fileserver/modules/vfs_acl_tdb.o
+VFS_SMB_TRAFFIC_ANALYZER_OBJ = ../fileserver/modules/vfs_smb_traffic_analyzer.o
+VFS_ONEFS_OBJ = ../fileserver/modules/vfs_onefs.o ../fileserver/modules/onefs_acl.o ../fileserver/modules/onefs_system.o \
+ ../fileserver/modules/onefs_open.o ../fileserver/modules/onefs_streams.o ../fileserver/modules/onefs_dir.o \
+ ../fileserver/modules/onefs_cbrl.o ../fileserver/modules/onefs_notify.o ../fileserver/modules/onefs_config.o
+VFS_ONEFS_SHADOW_COPY_OBJ = ../fileserver/modules/vfs_onefs_shadow_copy.o ../fileserver/modules/onefs_shadow_copy.o
+PERFCOUNT_ONEFS_OBJ = ../fileserver/modules/perfcount_onefs.o
+PERFCOUNT_TEST_OBJ = ../fileserver/modules/perfcount_test.o
+VFS_DIRSORT_OBJ = ../fileserver/modules/vfs_dirsort.o
+VFS_SCANNEDONLY_OBJ = ../fileserver/modules/vfs_scannedonly.o
+VFS_CROSSRENAME_OBJ = ../fileserver/modules/vfs_crossrename.o
PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o
auth/auth_compat.o auth/auth_ntlmssp.o \
$(PLAINTEXT_AUTH_OBJ) $(SLCACHE_OBJ) $(DCUTIL_OBJ)
-MANGLE_OBJ = smbd/mangle.o smbd/mangle_hash.o smbd/mangle_hash2.o
-
-SMBD_OBJ_MAIN = smbd/server.o
-
-BUILDOPT_OBJ = smbd/build_options.o
-
-SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \
- smbd/utmp.o smbd/session.o smbd/map_username.o \
- smbd/dfree.o smbd/dir.o smbd/password.o smbd/conn.o \
- smbd/share_access.o smbd/fileio.o \
- smbd/ipc.o smbd/lanman.o smbd/negprot.o \
- smbd/message.o smbd/nttrans.o smbd/pipes.o \
- smbd/reply.o smbd/sesssetup.o smbd/trans2.o smbd/uid.o \
- smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o \
- smbd/blocking.o smbd/sec_ctx.o smbd/srvstr.o \
- smbd/vfs.o smbd/perfcount.o smbd/statcache.o smbd/seal.o \
- smbd/posix_acls.o lib/sysacls.o \
- smbd/process.o smbd/service.o smbd/error.o \
- printing/printfsp.o lib/sysquotas.o lib/sysquotas_linux.o \
+MANGLE_OBJ = ../fileserver/mangle.o ../fileserver/mangle_hash.o ../fileserver/mangle_hash2.o
+
+SMBD_OBJ_MAIN = ../fileserver/server.o
+
+BUILDOPT_OBJ = ../fileserver/build_options.o
+
+SMBD_OBJ_SRV = ../fileserver/files.o ../fileserver/chgpasswd.o ../fileserver/connection.o \
+ ../fileserver/utmp.o ../fileserver/session.o ../fileserver/map_username.o \
+ ../fileserver/dfree.o ../fileserver/dir.o ../fileserver/password.o ../fileserver/conn.o \
+ ../fileserver/share_access.o ../fileserver/fileio.o \
+ ../fileserver/ipc.o ../fileserver/lanman.o ../fileserver/negprot.o \
+ ../fileserver/message.o ../fileserver/nttrans.o ../fileserver/pipes.o \
+ ../fileserver/reply.o ../fileserver/sesssetup.o ../fileserver/trans2.o ../fileserver/uid.o \
+ ../fileserver/dosmode.o ../fileserver/filename.o ../fileserver/open.o ../fileserver/close.o \
+ ../fileserver/blocking.o ../fileserver/sec_ctx.o ../fileserver/srvstr.o \
+ ../fileserver/vfs.o ../fileserver/perfcount.o ../fileserver/statcache.o ../fileserver/seal.o \
+ ../fileserver/posix_acls.o lib/sysacls.o \
+ ../fileserver/process.o ../fileserver/service.o ../fileserver/error.o \
+ ../fileserver/printing/printfsp.o lib/sysquotas.o lib/sysquotas_linux.o \
lib/sysquotas_xfs.o lib/sysquotas_4A.o \
- smbd/change_trust_pw.o smbd/fake_file.o \
- smbd/quotas.o smbd/ntquotas.o $(AFS_OBJ) smbd/msdfs.o \
- $(AFS_SETTOKEN_OBJ) smbd/aio.o smbd/statvfs.o \
- smbd/dmapi.o smbd/signing.o \
- smbd/file_access.o \
- smbd/dnsregister.o smbd/globals.o \
- smbd/smb2_server.o \
- smbd/smb2_signing.o \
- smbd/smb2_glue.o \
- smbd/smb2_negprot.o \
- smbd/smb2_sesssetup.o \
- smbd/smb2_tcon.o \
- smbd/smb2_create.o \
- smbd/smb2_close.o \
- smbd/smb2_flush.o \
- smbd/smb2_read.o \
- smbd/smb2_write.o \
- smbd/smb2_lock.o \
- smbd/smb2_ioctl.o \
- smbd/smb2_keepalive.o \
- smbd/smb2_find.o \
- smbd/smb2_notify.o \
- smbd/smb2_getinfo.o \
- smbd/smb2_setinfo.o \
- smbd/smb2_break.o \
+ ../fileserver/change_trust_pw.o ../fileserver/fake_file.o \
+ ../fileserver/quotas.o ../fileserver/ntquotas.o $(AFS_OBJ) ../fileserver/msdfs.o \
+ $(AFS_SETTOKEN_OBJ) ../fileserver/aio.o ../fileserver/statvfs.o \
+ ../fileserver/dmapi.o ../fileserver/signing.o \
+ ../fileserver/file_access.o \
+ ../fileserver/dnsregister.o ../fileserver/globals.o \
+ ../fileserver/smb2_server.o \
+ ../fileserver/smb2_signing.o \
+ ../fileserver/smb2_glue.o \
+ ../fileserver/smb2_negprot.o \
+ ../fileserver/smb2_sesssetup.o \
+ ../fileserver/smb2_tcon.o \
+ ../fileserver/smb2_create.o \
+ ../fileserver/smb2_close.o \
+ ../fileserver/smb2_flush.o \
+ ../fileserver/smb2_read.o \
+ ../fileserver/smb2_write.o \
+ ../fileserver/smb2_lock.o \
+ ../fileserver/smb2_ioctl.o \
+ ../fileserver/smb2_keepalive.o \
+ ../fileserver/smb2_find.o \
+ ../fileserver/smb2_notify.o \
+ ../fileserver/smb2_getinfo.o \
+ ../fileserver/smb2_setinfo.o \
+ ../fileserver/smb2_break.o \
../libcli/smb/smb2_create_blob.o \
$(MANGLE_OBJ) @VFS_STATIC@
$(LIBSMBCONF_OBJ) \
$(PRIVILEGES_BASIC_OBJ)
-PRINTING_OBJ = printing/pcap.o printing/print_svid.o printing/print_aix.o \
- printing/print_cups.o printing/print_generic.o \
- printing/lpq_parse.o printing/load.o \
- printing/print_iprint.o
+PRINTING_OBJ = ../fileserver/printing/pcap.o ../fileserver/printing/print_svid.o ../fileserver/printing/print_aix.o \
+ ../fileserver/printing/print_cups.o ../fileserver/printing/print_generic.o \
+ ../fileserver/printing/lpq_parse.o ../fileserver/printing/load.o \
+ ../fileserver/printing/print_iprint.o
-PRINTBASE_OBJ = printing/notify.o printing/printing_db.o
-PRINTBACKEND_OBJ = printing/printing.o printing/nt_printing.o $(PRINTBASE_OBJ)
+PRINTBASE_OBJ = ../fileserver/printing/notify.o ../fileserver/printing/printing_db.o
+PRINTBACKEND_OBJ = ../fileserver/printing/printing.o ../fileserver/printing/nt_printing.o $(PRINTBASE_OBJ)
SMBD_OBJ = $(SMBD_OBJ_BASE) $(SMBD_OBJ_MAIN)
$(SMBLDAP_OBJ) $(LIBSAMBA_OBJ) \
$(LDB_OBJ) $(LIBTSOCKET_OBJ)
-IDMAP_OBJ = winbindd/idmap.o winbindd/idmap_util.o @IDMAP_STATIC@
+IDMAP_OBJ = ../authserver/idmap.o ../authserver/idmap_util.o @IDMAP_STATIC@
-NSS_INFO_OBJ = winbindd/nss_info.o @NSS_INFO_STATIC@
+NSS_INFO_OBJ = ../authserver/nss_info.o @NSS_INFO_STATIC@
IDMAP_HASH_OBJ = \
- winbindd/idmap_hash/idmap_hash.o \
- winbindd/idmap_hash/mapfile.o
+ ../authserver/idmap_hash/idmap_hash.o \
+ ../authserver/idmap_hash/mapfile.o
IDMAP_ADEX_OBJ = \
- winbindd/idmap_adex/idmap_adex.o \
- winbindd/idmap_adex/cell_util.o \
- winbindd/idmap_adex/likewise_cell.o \
- winbindd/idmap_adex/provider_unified.o \
- winbindd/idmap_adex/gc_util.o \
- winbindd/idmap_adex/domain_util.o
+ ../authserver/idmap_adex/idmap_adex.o \
+ ../authserver/idmap_adex/cell_util.o \
+ ../authserver/idmap_adex/likewise_cell.o \
+ ../authserver/idmap_adex/provider_unified.o \
+ ../authserver/idmap_adex/gc_util.o \
+ ../authserver/idmap_adex/domain_util.o
WINBINDD_OBJ1 = \
- winbindd/winbindd.o \
- winbindd/winbindd_group.o \
- winbindd/winbindd_util.o \
- winbindd/winbindd_cache.o \
- winbindd/winbindd_pam.o \
- winbindd/winbindd_misc.o \
- winbindd/winbindd_cm.o \
- winbindd/winbindd_wins.o \
- winbindd/winbindd_rpc.o \
- winbindd/winbindd_reconnect.o \
- winbindd/winbindd_ads.o \
- winbindd/winbindd_passdb.o \
- winbindd/winbindd_dual.o \
- winbindd/winbindd_dual_ndr.o \
- winbindd/winbindd_dual_srv.o \
+ ../authserver/winbindd.o \
+ ../authserver/winbindd_group.o \
+ ../authserver/winbindd_util.o \
+ ../authserver/winbindd_cache.o \
+ ../authserver/winbindd_pam.o \
+ ../authserver/winbindd_misc.o \
+ ../authserver/winbindd_cm.o \
+ ../authserver/winbindd_wins.o \
+ ../authserver/winbindd_rpc.o \
+ ../authserver/winbindd_reconnect.o \
+ ../authserver/winbindd_ads.o \
+ ../authserver/winbindd_passdb.o \
+ ../authserver/winbindd_dual.o \
+ ../authserver/winbindd_dual_ndr.o \
+ ../authserver/winbindd_dual_srv.o \
librpc/gen_ndr/cli_wbint.o \
librpc/gen_ndr/srv_wbint.o \
librpc/gen_ndr/ndr_wbint.o \
- winbindd/winbindd_async.o \
- winbindd/winbindd_creds.o \
- winbindd/winbindd_cred_cache.o \
- winbindd/winbindd_ccache_access.o \
- winbindd/winbindd_domain.o \
- winbindd/winbindd_idmap.o \
- winbindd/winbindd_locator.o \
- winbindd/winbindd_ndr.o \
- winbindd/wb_ping.o \
- winbindd/wb_lookupsid.o \
- winbindd/wb_lookupname.o \
- winbindd/wb_sid2uid.o \
- winbindd/wb_sid2gid.o \
- winbindd/wb_uid2sid.o \
- winbindd/wb_gid2sid.o \
- winbindd/wb_queryuser.o \
- winbindd/wb_lookupuseraliases.o \
- winbindd/wb_lookupusergroups.o \
- winbindd/wb_getpwsid.o \
- winbindd/wb_gettoken.o \
- winbindd/wb_seqnum.o \
- winbindd/wb_seqnums.o \
- winbindd/wb_group_members.o \
- winbindd/wb_getgrsid.o \
- winbindd/wb_query_user_list.o \
- winbindd/wb_fill_pwent.o \
- winbindd/wb_next_pwent.o \
- winbindd/wb_next_grent.o \
- winbindd/wb_dsgetdcname.o \
- winbindd/winbindd_lookupsid.o \
- winbindd/winbindd_lookupname.o \
- winbindd/winbindd_sid_to_uid.o \
- winbindd/winbindd_sid_to_gid.o \
- winbindd/winbindd_uid_to_sid.o \
- winbindd/winbindd_gid_to_sid.o \
- winbindd/winbindd_allocate_uid.o \
- winbindd/winbindd_allocate_gid.o \
- winbindd/winbindd_getpwsid.o \
- winbindd/winbindd_getpwnam.o \
- winbindd/winbindd_getpwuid.o \
- winbindd/winbindd_getsidaliases.o \
- winbindd/winbindd_getuserdomgroups.o \
- winbindd/winbindd_getgroups.o \
- winbindd/winbindd_show_sequence.o \
- winbindd/winbindd_getgrgid.o \
- winbindd/winbindd_getgrnam.o \
- winbindd/winbindd_getusersids.o \
- winbindd/winbindd_lookuprids.o \
- winbindd/winbindd_setpwent.o \
- winbindd/winbindd_getpwent.o \
- winbindd/winbindd_endpwent.o \
- winbindd/winbindd_setgrent.o \
- winbindd/winbindd_getgrent.o \
- winbindd/winbindd_endgrent.o \
- winbindd/winbindd_dsgetdcname.o \
- winbindd/winbindd_getdcname.o \
- winbindd/winbindd_list_users.o \
- winbindd/winbindd_list_groups.o \
- winbindd/winbindd_check_machine_acct.o \
- winbindd/winbindd_change_machine_acct.o \
- winbindd/winbindd_ping_dc.o \
- winbindd/winbindd_set_mapping.o \
- winbindd/winbindd_remove_mapping.o \
- winbindd/winbindd_set_hwm.o \
- winbindd/winbindd_pam_auth.o \
- winbindd/winbindd_pam_auth_crap.o \
- winbindd/winbindd_pam_chauthtok.o \
- winbindd/winbindd_pam_logoff.o \
+ ../authserver/winbindd_async.o \
+ ../authserver/winbindd_creds.o \
+ ../authserver/winbindd_cred_cache.o \
+ ../authserver/winbindd_ccache_access.o \
+ ../authserver/winbindd_domain.o \
+ ../authserver/winbindd_idmap.o \
+ ../authserver/winbindd_locator.o \
+ ../authserver/winbindd_ndr.o \
+ ../authserver/wb_ping.o \
+ ../authserver/wb_lookupsid.o \
+ ../authserver/wb_lookupname.o \
+ ../authserver/wb_sid2uid.o \
+ ../authserver/wb_sid2gid.o \
+ ../authserver/wb_uid2sid.o \
+ ../authserver/wb_gid2sid.o \
+ ../authserver/wb_queryuser.o \
+ ../authserver/wb_lookupuseraliases.o \
+ ../authserver/wb_lookupusergroups.o \
+ ../authserver/wb_getpwsid.o \
+ ../authserver/wb_gettoken.o \
+ ../authserver/wb_seqnum.o \
+ ../authserver/wb_seqnums.o \
+ ../authserver/wb_group_members.o \
+ ../authserver/wb_getgrsid.o \
+ ../authserver/wb_query_user_list.o \
+ ../authserver/wb_fill_pwent.o \
+ ../authserver/wb_next_pwent.o \
+ ../authserver/wb_next_grent.o \
+ ../authserver/wb_dsgetdcname.o \
+ ../authserver/winbindd_lookupsid.o \
+ ../authserver/winbindd_lookupname.o \
+ ../authserver/winbindd_sid_to_uid.o \
+ ../authserver/winbindd_sid_to_gid.o \
+ ../authserver/winbindd_uid_to_sid.o \
+ ../authserver/winbindd_gid_to_sid.o \
+ ../authserver/winbindd_allocate_uid.o \
+ ../authserver/winbindd_allocate_gid.o \
+ ../authserver/winbindd_getpwsid.o \
+ ../authserver/winbindd_getpwnam.o \
+ ../authserver/winbindd_getpwuid.o \
+ ../authserver/winbindd_getsidaliases.o \
+ ../authserver/winbindd_getuserdomgroups.o \
+ ../authserver/winbindd_getgroups.o \
+ ../authserver/winbindd_show_sequence.o \
+ ../authserver/winbindd_getgrgid.o \
+ ../authserver/winbindd_getgrnam.o \
+ ../authserver/winbindd_getusersids.o \
+ ../authserver/winbindd_lookuprids.o \
+ ../authserver/winbindd_setpwent.o \
+ ../authserver/winbindd_getpwent.o \
+ ../authserver/winbindd_endpwent.o \
+ ../authserver/winbindd_setgrent.o \
+ ../authserver/winbindd_getgrent.o \
+ ../authserver/winbindd_endgrent.o \
+ ../authserver/winbindd_dsgetdcname.o \
+ ../authserver/winbindd_getdcname.o \
+ ../authserver/winbindd_list_users.o \
+ ../authserver/winbindd_list_groups.o \
+ ../authserver/winbindd_check_machine_acct.o \
+ ../authserver/winbindd_change_machine_acct.o \
+ ../authserver/winbindd_ping_dc.o \
+ ../authserver/winbindd_set_mapping.o \
+ ../authserver/winbindd_remove_mapping.o \
+ ../authserver/winbindd_set_hwm.o \
+ ../authserver/winbindd_pam_auth.o \
+ ../authserver/winbindd_pam_auth_crap.o \
+ ../authserver/winbindd_pam_chauthtok.o \
+ ../authserver/winbindd_pam_logoff.o \
auth/token_util.o \
auth/check_samsec.o \
auth/server_info.o \
auth/server_info_sam.o \
auth/user_info.o \
auth/pampass.o \
- smbd/chgpasswd.o \
+ ../fileserver/chgpasswd.o \
../nsswitch/libwbclient/wb_reqtrans.o
WINBINDD_OBJ = \
$(LIBNDR_GEN_OBJ0) $(LIBNDR_GEN_OBJ1) @BUILD_INIPARSER@
-VLP_OBJ = printing/tests/vlp.o \
+VLP_OBJ = ../fileserver/printing/tests/vlp.o \
../lib/util/util_tdb.o \
$(LIBSAMBAUTIL_OBJ) \
param/util.o
echo "$(COMPILE_CC_PATH)" 1>&2;\
$(COMPILE_CC_PATH) >/dev/null 2>&1
-smbd/build_options.o: smbd/build_options.c Makefile include/config.h include/build_env.h include/proto.h
+../fileserver/build_options.o: ../fileserver/build_options.c Makefile include/config.h include/build_env.h include/proto.h
@echo Compiling $*.c
@$(COMPILE_CC_PATH) && exit 0;\
echo "The following command failed:" 1>&2;\
echo "$(COMPILE_CC_PATH)" 1>&2;\
$(COMPILE_CC_PATH) >/dev/null 2>&1
-smbd/build_options.c: include/config.h.in script/mkbuildoptions.awk
+../fileserver/build_options.c: include/config.h.in script/mkbuildoptions.awk
@echo Generating $@
- @dir=smbd $(MAKEDIR) && $(AWK) -f $(srcdir)/script/mkbuildoptions.awk > $(builddir)/smbd/build_options.c < $(srcdir)/include/config.h.in
+ @dir=smbd $(MAKEDIR) && $(AWK) -f $(srcdir)/script/mkbuildoptions.awk > $(builddir)/../fileserver/build_options.c < $(srcdir)/include/config.h.in
bin/.dummy:
@if (: >> $@ || : > $@) >/dev/null 2>&1; then :; else \
@echo "Building plugin $@"
@$(SHLD_MODULE) passdb/pdb_smbpasswd.o
-bin/rid.@SHLIBEXT@: $(BINARY_PREREQS) winbindd/idmap_rid.o
+bin/rid.@SHLIBEXT@: $(BINARY_PREREQS) ../authserver/idmap_rid.o
@echo "Building plugin $@"
- @$(SHLD_MODULE) winbindd/idmap_rid.o
+ @$(SHLD_MODULE) ../authserver/idmap_rid.o
-bin/ad.@SHLIBEXT@: $(BINARY_PREREQS) winbindd/idmap_ad.o
+bin/ad.@SHLIBEXT@: $(BINARY_PREREQS) ../authserver/idmap_ad.o
@echo "Building plugin $@"
- @$(SHLD_MODULE) winbindd/idmap_ad.o
+ @$(SHLD_MODULE) ../authserver/idmap_ad.o
bin/hash.@SHLIBEXT@: $(BINARY_PREREQS) $(IDMAP_HASH_OBJ)
@echo "Building plugin $@"
@echo "Building plugin $@"
@$(SHLD_MODULE) $(IDMAP_ADEX_OBJ)
-bin/tdb2.@SHLIBEXT@: $(BINARY_PREREQS) winbindd/idmap_tdb2.o
+bin/tdb2.@SHLIBEXT@: $(BINARY_PREREQS) ../authserver/idmap_tdb2.o
@echo "Building plugin $@"
- @$(SHLD_MODULE) winbindd/idmap_tdb2.o
+ @$(SHLD_MODULE) ../authserver/idmap_tdb2.o
-bin/ldap.@SHLIBEXT@: $(BINARY_PREREQS) winbindd/idmap_ldap.o
+bin/ldap.@SHLIBEXT@: $(BINARY_PREREQS) ../authserver/idmap_ldap.o
@echo "Building plugin $@"
- @$(SHLD_MODULE) winbindd/idmap_ldap.o
+ @$(SHLD_MODULE) ../authserver/idmap_ldap.o
bin/weird.@SHLIBEXT@: $(BINARY_PREREQS) $(DEVEL_HELP_WEIRD_OBJ)
@echo "Building plugin $@"
clean:: cleanlibs
-rm -f include/build_env.h
- -rm -f smbd/build_options.c
+ -rm -f ../fileserver/build_options.c
-rm -f $(PRECOMPILED_HEADER)
-rm -f core */*~ *~ \
*/*.o */*/*.o */*/*/*.o */*/*/*/*.o \
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/auth/libcli_auth.h"
#undef DBGC_CLASS
*/
#include "includes.h"
-#include "smbd/globals.h"
+#include "fileserver/globals.h"
#include "../libcli/auth/libcli_auth.h"
#undef DBGC_CLASS
SMB_MODULE(rpc_rpcecho, \$(RPC_ECHO_OBJ), "bin/librpc_rpcecho.$SHLIBEXT", RPC)
SMB_SUBSYSTEM(RPC,smbd/process.o)
-SMB_MODULE(idmap_ldap, winbindd/idmap_ldap.o, "bin/ldap.$SHLIBEXT", IDMAP)
-SMB_MODULE(idmap_tdb, winbindd/idmap_tdb.o, "bin/tdb.$SHLIBEXT", IDMAP)
-SMB_MODULE(idmap_tdb2, winbindd/idmap_tdb2.o, "bin/tdb2.$SHLIBEXT", IDMAP)
-SMB_MODULE(idmap_passdb, winbindd/idmap_passdb.o, "bin/passdb.$SHLIBEXT", IDMAP)
-SMB_MODULE(idmap_nss, winbindd/idmap_nss.o, "bin/nss.$SHLIBEXT", IDMAP)
-SMB_MODULE(idmap_rid, winbindd/idmap_rid.o, "bin/rid.$SHLIBEXT", IDMAP)
-SMB_MODULE(idmap_ad, winbindd/idmap_ad.o, "bin/ad.$SHLIBEXT", IDMAP)
+SMB_MODULE(idmap_ldap, ../authserver/idmap_ldap.o, "bin/ldap.$SHLIBEXT", IDMAP)
+SMB_MODULE(idmap_tdb, ../authserver/idmap_tdb.o, "bin/tdb.$SHLIBEXT", IDMAP)
+SMB_MODULE(idmap_tdb2, ../authserver/idmap_tdb2.o, "bin/tdb2.$SHLIBEXT", IDMAP)
+SMB_MODULE(idmap_passdb, ../authserver/idmap_passdb.o, "bin/passdb.$SHLIBEXT", IDMAP)
+SMB_MODULE(idmap_nss, ../authserver/idmap_nss.o, "bin/nss.$SHLIBEXT", IDMAP)
+SMB_MODULE(idmap_rid, ../authserver/idmap_rid.o, "bin/rid.$SHLIBEXT", IDMAP)
+SMB_MODULE(idmap_ad, ../authserver/idmap_ad.o, "bin/ad.$SHLIBEXT", IDMAP)
SMB_MODULE(idmap_hash, \$(IDMAP_HASH_OBJ), "bin/hash.$SHLIBEXT", IDMAP)
SMB_MODULE(idmap_adex, \$(IDMAP_ADEX_OBJ), "bin/adex.$SHLIBEXT", IDMAP)
-SMB_SUBSYSTEM(IDMAP, winbindd/idmap.o)
+SMB_SUBSYSTEM(IDMAP, authserver/idmap.o)
-SMB_MODULE(nss_info_template, winbindd/nss_info_template.o, "bin/template.$SHLIBEXT", NSS_INFO)
-SMB_SUBSYSTEM(NSS_INFO, winbindd/nss_info.o)
+SMB_MODULE(nss_info_template, ../authserver/nss_info_template.o, "bin/template.$SHLIBEXT", NSS_INFO)
+SMB_SUBSYSTEM(NSS_INFO, ../authserver/nss_info.o)
-SMB_MODULE(charset_weird, modules/weird.o, "bin/weird.$SHLIBEXT", CHARSET)
-SMB_MODULE(charset_CP850, modules/CP850.o, "bin/CP850.$SHLIBEXT", CHARSET)
-SMB_MODULE(charset_CP437, modules/CP437.o, "bin/CP437.$SHLIBEXT", CHARSET)
-SMB_MODULE(charset_macosxfs, modules/charset_macosxfs.o,"bin/macosxfs.$SHLIBEXT", CHARSET)
+SMB_MODULE(charset_weird, ../fileserver/modules/weird.o, "bin/weird.$SHLIBEXT", CHARSET)
+SMB_MODULE(charset_CP850, ../fileserver/modules/CP850.o, "bin/CP850.$SHLIBEXT", CHARSET)
+SMB_MODULE(charset_CP437, ../fileserver/modules/CP437.o, "bin/CP437.$SHLIBEXT", CHARSET)
+SMB_MODULE(charset_macosxfs, ../fileserver/modules/charset_macosxfs.o,"bin/macosxfs.$SHLIBEXT", CHARSET)
SMB_SUBSYSTEM(CHARSET,lib/iconv.o)
SMB_MODULE(auth_sam, \$(AUTH_SAM_OBJ), "bin/sam.$SHLIBEXT", AUTH)
NUM_FLUSH_REASONS};
#include "nss_info.h"
-#include "modules/nfs4_acls.h"
+#include "../fileserver/modules/nfs4_acls.h"
#include "nsswitch/libwbclient/wbclient.h"
/***** prototypes *****/
+++ /dev/null
-/*
- Unix SMB/CIFS implementation.
- load printer lists
- Copyright (C) Andrew Tridgell 1992-2000
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-
-
-/***************************************************************************
-auto-load some homes and printer services
-***************************************************************************/
-static void add_auto_printers(void)
-{
- const char *p;
- int pnum = lp_servicenumber(PRINTERS_NAME);
- char *str;
- char *saveptr;
-
- if (pnum < 0)
- return;
-
- if ((str = SMB_STRDUP(lp_auto_services())) == NULL)
- return;
-
- for (p = strtok_r(str, LIST_SEP, &saveptr); p;
- p = strtok_r(NULL, LIST_SEP, &saveptr)) {
- if (lp_servicenumber(p) >= 0)
- continue;
-
- if (pcap_printername_ok(p))
- lp_add_printer(p, pnum);
- }
-
- SAFE_FREE(str);
-}
-
-/***************************************************************************
-load automatic printer services
-***************************************************************************/
-void load_printers(void)
-{
- if (!pcap_cache_loaded())
- pcap_cache_reload();
-
- add_auto_printers();
-
- /* load all printcap printers */
- if (lp_load_printers() && lp_servicenumber(PRINTERS_NAME) >= 0)
- pcap_printer_fn(lp_add_one_printer, NULL);
-}
+++ /dev/null
-/*
- Unix SMB/CIFS implementation.
- lpq parsing routines
- Copyright (C) Andrew Tridgell 2000
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "printing.h"
-
-static const char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Err"};
-
-
-/*******************************************************************
- Process time fields
-********************************************************************/
-
-static time_t EntryTime(char *tok[], int ptr, int count, int minimum)
-{
- time_t jobtime,jobtime1;
-
- jobtime = time(NULL); /* default case: take current time */
- if (count >= minimum) {
- struct tm *t;
- int i, day, hour, min, sec;
-
- for (i=0; i<13; i++) {
- if (!strncmp(tok[ptr], Months[i],3)) {
- break; /* Find month */
- }
- }
-
- if (i<12) {
- fstring c;
- t = localtime(&jobtime);
- if (!t) {
- return (time_t)-1;
- }
- day = atoi(tok[ptr+1]);
- fstrcpy(c,tok[ptr+2]);
- *(c+2)=0;
- hour = atoi(c);
- *(c+5)=0;
- min = atoi(c+3);
- if(*(c+6) != 0) {
- sec = atoi(c+6);
- } else {
- sec=0;
- }
-
- if ((t->tm_mon < i)|| ((t->tm_mon == i)&&
- ((t->tm_mday < day)||
- ((t->tm_mday == day)&&
- (t->tm_hour*60+t->tm_min < hour*60+min))))) {
- t->tm_year--; /* last year's print job */
- }
-
- t->tm_mon = i;
- t->tm_mday = day;
- t->tm_hour = hour;
- t->tm_min = min;
- t->tm_sec = sec;
- jobtime1 = mktime(t);
- if (jobtime1 != (time_t)-1) {
- jobtime = jobtime1;
- }
- }
- }
- return jobtime;
-}
-
-/****************************************************************************
-parse a lpq line
-
-here is an example of lpq output under bsd
-
-Warning: no daemon present
-Rank Owner Job Files Total Size
-1st tridge 148 README 8096 bytes
-
-here is an example of lpq output under osf/1
-
-Warning: no daemon present
-Rank Pri Owner Job Files Total Size
-1st 0 tridge 148 README 8096 bytes
-
-
-<allan@umich.edu> June 30, 1998.
-Modified to handle file names with spaces, like the parse_lpq_lprng code
-further below.
-****************************************************************************/
-
-static bool parse_lpq_bsd(char *line,print_queue_struct *buf,bool first)
-{
-#ifdef OSF1
-#define RANKTOK 0
-#define PRIOTOK 1
-#define USERTOK 2
-#define JOBTOK 3
-#define FILETOK 4
-#define TOTALTOK (count - 2)
-#define NTOK 6
-#define MAXTOK 128
-#else /* OSF1 */
-#define RANKTOK 0
-#define USERTOK 1
-#define JOBTOK 2
-#define FILETOK 3
-#define TOTALTOK (count - 2)
-#define NTOK 5
-#define MAXTOK 128
-#endif /* OSF1 */
-
- char *tok[MAXTOK];
- int count = 0;
- TALLOC_CTX *ctx = talloc_tos();
- char *line2 = NULL;
- char *saveptr;
-
- line2 = talloc_strdup(ctx, line);
- if (!line2) {
- return false;
- }
-
-#ifdef OSF1
- {
- size_t length;
- length = strlen(line2);
- if (line2[length-3] == ':') {
- return False;
- }
- }
-#endif /* OSF1 */
-
- /* FIXME: Use next_token_talloc rather than strtok! */
- tok[0] = strtok_r(line2," \t", &saveptr);
- count++;
-
- while ((count < MAXTOK)
- && ((tok[count] = strtok_r(NULL, " \t", &saveptr)) != NULL)) {
- count++;
- }
-
- /* we must get at least NTOK tokens */
- if (count < NTOK) {
- return False;
- }
-
- /* the Job and Total columns must be integer */
- if (!isdigit((int)*tok[JOBTOK]) || !isdigit((int)*tok[TOTALTOK])) {
- return False;
- }
-
- buf->job = atoi(tok[JOBTOK]);
- buf->size = atoi(tok[TOTALTOK]);
- buf->status = strequal(tok[RANKTOK],"active")?LPQ_PRINTING:LPQ_QUEUED;
- buf->time = time(NULL);
- fstrcpy(buf->fs_user,tok[USERTOK]);
- fstrcpy(buf->fs_file,tok[FILETOK]);
-
- if ((FILETOK + 1) != TOTALTOK) {
- int i;
-
- for (i = (FILETOK + 1); i < TOTALTOK; i++) {
- /* FIXME: Using fstrcat rather than other means is a bit
- * inefficient; this might be a problem for enormous queues with
- * many fields. */
- fstrcat(buf->fs_file, " ");
- fstrcat(buf->fs_file, tok[i]);
- }
- /* Ensure null termination. */
- buf->fs_file[sizeof(buf->fs_file)-1] = '\0';
- }
-
-#ifdef PRIOTOK
- buf->priority = atoi(tok[PRIOTOK]);
-#else
- buf->priority = 1;
-#endif
- return True;
-}
-
-/*
-<magnus@hum.auc.dk>
-LPRng_time modifies the current date by inserting the hour and minute from
-the lpq output. The lpq time looks like "23:15:07"
-
-<allan@umich.edu> June 30, 1998.
-Modified to work with the re-written parse_lpq_lprng routine.
-
-<J.P.M.v.Itegem@tue.nl> Dec 17,1999
-Modified to work with lprng 3.16
-With lprng 3.16 The lpq time looks like
- "23:15:07"
- "23:15:07.100"
- "1999-12-16-23:15:07"
- "1999-12-16-23:15:07.100"
-
-*/
-static time_t LPRng_time(char *time_string)
-{
- time_t jobtime;
- struct tm *t;
-
- jobtime = time(NULL); /* default case: take current time */
- t = localtime(&jobtime);
- if (!t) {
- return (time_t)-1;
- }
-
- if ( atoi(time_string) < 24 ){
- t->tm_hour = atoi(time_string);
- t->tm_min = atoi(time_string+3);
- t->tm_sec = atoi(time_string+6);
- } else {
- t->tm_year = atoi(time_string)-1900;
- t->tm_mon = atoi(time_string+5)-1;
- t->tm_mday = atoi(time_string+8);
- t->tm_hour = atoi(time_string+11);
- t->tm_min = atoi(time_string+14);
- t->tm_sec = atoi(time_string+17);
- }
- jobtime = mktime(t);
-
- return jobtime;
-}
-
-/****************************************************************************
- parse a lprng lpq line
- <allan@umich.edu> June 30, 1998.
- Re-wrote this to handle file names with spaces, multiple file names on one
- lpq line, etc;
-
-****************************************************************************/
-
-static bool parse_lpq_lprng(char *line,print_queue_struct *buf,bool first)
-{
-#define LPRNG_RANKTOK 0
-#define LPRNG_USERTOK 1
-#define LPRNG_PRIOTOK 2
-#define LPRNG_JOBTOK 3
-#define LPRNG_FILETOK 4
-#define LPRNG_TOTALTOK (num_tok - 2)
-#define LPRNG_TIMETOK (num_tok - 1)
-#define LPRNG_NTOK 7
-#define LPRNG_MAXTOK 128 /* PFMA just to keep us from running away. */
-
- char *tokarr[LPRNG_MAXTOK];
- const char *cptr;
- char *ptr;
- int num_tok = 0;
- TALLOC_CTX *frame = talloc_stackframe();
-
- cptr = line;
- while((num_tok < LPRNG_MAXTOK) && next_token_talloc(frame, &cptr,
- &tokarr[num_tok], " \t")) {
- num_tok++;
- }
-
- /* We must get at least LPRNG_NTOK tokens. */
- if (num_tok < LPRNG_NTOK) {
- TALLOC_FREE(frame);
- return False;
- }
-
- if (!isdigit((int)*tokarr[LPRNG_JOBTOK]) || !isdigit((int)*tokarr[LPRNG_TOTALTOK])) {
- TALLOC_FREE(frame);
- return False;
- }
-
- buf->job = atoi(tokarr[LPRNG_JOBTOK]);
- buf->size = atoi(tokarr[LPRNG_TOTALTOK]);
-
- if (strequal(tokarr[LPRNG_RANKTOK],"active")) {
- buf->status = LPQ_PRINTING;
- } else if (strequal(tokarr[LPRNG_RANKTOK],"done")) {
- buf->status = LPQ_PRINTED;
- } else if (isdigit((int)*tokarr[LPRNG_RANKTOK])) {
- buf->status = LPQ_QUEUED;
- } else {
- buf->status = LPQ_PAUSED;
- }
-
- buf->priority = *tokarr[LPRNG_PRIOTOK] -'A';
-
- buf->time = LPRng_time(tokarr[LPRNG_TIMETOK]);
-
- fstrcpy(buf->fs_user,tokarr[LPRNG_USERTOK]);
-
- /* The '@hostname' prevents windows from displaying the printing icon
- * for the current user on the taskbar. Plop in a null.
- */
-
- if ((ptr = strchr_m(buf->fs_user,'@')) != NULL) {
- *ptr = '\0';
- }
-
- fstrcpy(buf->fs_file,tokarr[LPRNG_FILETOK]);
-
- if ((LPRNG_FILETOK + 1) != LPRNG_TOTALTOK) {
- int i;
-
- for (i = (LPRNG_FILETOK + 1); i < LPRNG_TOTALTOK; i++) {
- /* FIXME: Using fstrcat rather than other means is a bit
- * inefficient; this might be a problem for enormous queues with
- * many fields. */
- fstrcat(buf->fs_file, " ");
- fstrcat(buf->fs_file, tokarr[i]);
- }
- /* Ensure null termination. */
- buf->fs_file[sizeof(buf->fs_file)-1] = '\0';
- }
-
- TALLOC_FREE(frame);
- return True;
-}
-
-/*******************************************************************
-parse lpq on an aix system
-
-Queue Dev Status Job Files User PP % Blks Cp Rnk
-------- ----- --------- --- ------------------ ---------- ---- -- ----- --- ---
-lazer lazer READY
-lazer lazer RUNNING 537 6297doc.A kvintus@IE 0 10 2445 1 1
- QUEUED 538 C.ps root@IEDVB 124 1 2
- QUEUED 539 E.ps root@IEDVB 28 1 3
- QUEUED 540 L.ps root@IEDVB 172 1 4
- QUEUED 541 P.ps root@IEDVB 22 1 5
-********************************************************************/
-
-static bool parse_lpq_aix(char *line,print_queue_struct *buf,bool first)
-{
- char *tok[11];
- int count=0;
- const char *cline = line;
- TALLOC_CTX *frame = talloc_stackframe();
-
- /* handle the case of "(standard input)" as a filename */
- string_sub(line,"standard input","STDIN",0);
- all_string_sub(line,"(","\"",0);
- all_string_sub(line,")","\"",0);
-
- for (count=0; count<10 &&
- next_token_talloc(frame,&cline,&tok[count],NULL); count++) {
- ;
- }
-
- /* we must get 6 tokens */
- if (count < 10) {
- if ((count == 7) && ((strcmp(tok[0],"QUEUED") == 0) || (strcmp(tok[0],"HELD") == 0))) {
- /* the 2nd and 5th columns must be integer */
- if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4])) {
- TALLOC_FREE(frame);
- return False;
- }
- buf->size = atoi(tok[4]) * 1024;
- /* if the fname contains a space then use STDIN */
- if (strchr_m(tok[2],' ')) {
- tok[2] = talloc_strdup(frame,"STDIN");
- if (!tok[2]) {
- TALLOC_FREE(frame);
- return false;
- }
- }
-
- /* only take the last part of the filename */
- {
- char *p = strrchr_m(tok[2],'/');
- if (p) {
- tok[2] = p+1;
- }
- }
-
- buf->job = atoi(tok[1]);
- buf->status = strequal(tok[0],"HELD")?LPQ_PAUSED:LPQ_QUEUED;
- buf->priority = 0;
- buf->time = time(NULL);
- fstrcpy(buf->fs_user,tok[3]);
- fstrcpy(buf->fs_file,tok[2]);
- } else {
- DEBUG(6,("parse_lpq_aix count=%d\n", count));
- TALLOC_FREE(frame);
- return False;
- }
- } else {
- /* the 4th and 9th columns must be integer */
- if (!isdigit((int)*tok[3]) || !isdigit((int)*tok[8])) {
- TALLOC_FREE(frame);
- return False;
- }
-
- buf->size = atoi(tok[8]) * 1024;
- /* if the fname contains a space then use STDIN */
- if (strchr_m(tok[4],' ')) {
- tok[4] = talloc_strdup(frame,"STDIN");
- if (!tok[4]) {
- TALLOC_FREE(frame);
- return false;
- }
- }
-
- /* only take the last part of the filename */
- {
- char *p = strrchr_m(tok[4],'/');
- if (p) {
- tok[4] = p+1;
- }
- }
-
- buf->job = atoi(tok[3]);
- buf->status = strequal(tok[2],"RUNNING")?LPQ_PRINTING:LPQ_QUEUED;
- buf->priority = 0;
- buf->time = time(NULL);
- fstrcpy(buf->fs_user,tok[5]);
- fstrcpy(buf->fs_file,tok[4]);
- }
-
- TALLOC_FREE(frame);
- return True;
-}
-
-/****************************************************************************
-parse a lpq line
-here is an example of lpq output under hpux; note there's no space after -o !
-$> lpstat -oljplus
-ljplus-2153 user priority 0 Jan 19 08:14 on ljplus
- util.c 125697 bytes
- server.c 110712 bytes
-ljplus-2154 user priority 0 Jan 19 08:14 from client
- (standard input) 7551 bytes
-****************************************************************************/
-
-static bool parse_lpq_hpux(char *line, print_queue_struct *buf, bool first)
-{
- /* must read two lines to process, therefore keep some values static */
- static bool header_line_ok=False, base_prio_reset=False;
- static char *jobuser;
- static int jobid;
- static int jobprio;
- static time_t jobtime;
- static int jobstat=LPQ_QUEUED;
- /* to store minimum priority to print, lpstat command should be invoked
- with -p option first, to work */
- static int base_prio;
- int count;
- char htab = '\011';
- const char *cline = line;
- char *tok[12];
- TALLOC_CTX *frame = talloc_stackframe();
-
- /* If a line begins with a horizontal TAB, it is a subline type */
-
- if (line[0] == htab) { /* subline */
- /* check if it contains the base priority */
- if (!strncmp(line,"\tfence priority : ",18)) {
- base_prio=atoi(&line[18]);
- DEBUG(4, ("fence priority set at %d\n", base_prio));
- }
-
- if (!header_line_ok) {
- TALLOC_FREE(frame);
- return False; /* incorrect header line */
- }
-
- /* handle the case of "(standard input)" as a filename */
- string_sub(line,"standard input","STDIN",0);
- all_string_sub(line,"(","\"",0);
- all_string_sub(line,")","\"",0);
-
- for (count=0; count<2 &&
- next_token_talloc(frame, &cline, &tok[count],NULL);
- count++) {
- ;
- }
- /* we must get 2 tokens */
- if (count < 2) {
- TALLOC_FREE(frame);
- return False;
- }
-
- /* the 2nd column must be integer */
- if (!isdigit((int)*tok[1])) {
- TALLOC_FREE(frame);
- return False;
- }
-
- /* if the fname contains a space then use STDIN */
- if (strchr_m(tok[0],' ')) {
- tok[0] = talloc_strdup(frame, "STDIN");
- if (!tok[0]) {
- TALLOC_FREE(frame);
- return false;
- }
- }
-
- buf->size = atoi(tok[1]);
- fstrcpy(buf->fs_file,tok[0]);
-
- /* fill things from header line */
- buf->time = jobtime;
- buf->job = jobid;
- buf->status = jobstat;
- buf->priority = jobprio;
- if (jobuser) {
- fstrcpy(buf->fs_user,jobuser);
- } else {
- buf->fs_user[0] = '\0';
- }
-
- TALLOC_FREE(frame);
- return True;
- } else { /* header line */
- header_line_ok=False; /* reset it */
- if (first) {
- if (!base_prio_reset) {
- base_prio=0; /* reset it */
- base_prio_reset=True;
- }
- } else if (base_prio) {
- base_prio_reset=False;
- }
-
- /* handle the dash in the job id */
- string_sub(line,"-"," ",0);
-
- for (count=0; count<12 &&
- next_token_talloc(frame, &cline, &tok[count],NULL);
- count++) {
- ;
- }
-
- /* we must get 8 tokens */
- if (count < 8) {
- TALLOC_FREE(frame);
- return False;
- }
-
- /* first token must be printer name (cannot check ?) */
- /* the 2nd, 5th & 7th column must be integer */
- if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4]) || !isdigit((int)*tok[6])) {
- TALLOC_FREE(frame);
- return False;
- }
- jobid = atoi(tok[1]);
- SAFE_FREE(jobuser);
- jobuser = SMB_STRDUP(tok[2]);
- jobprio = atoi(tok[4]);
-
- /* process time */
- jobtime=EntryTime(tok, 5, count, 8);
- if (jobprio < base_prio) {
- jobstat = LPQ_PAUSED;
- DEBUG (4, ("job %d is paused: prio %d < %d; jobstat=%d\n",
- jobid, jobprio, base_prio, jobstat));
- } else {
- jobstat = LPQ_QUEUED;
- if ((count >8) && (((strequal(tok[8],"on")) ||
- ((strequal(tok[8],"from")) &&
- ((count > 10)&&(strequal(tok[10],"on"))))))) {
- jobstat = LPQ_PRINTING;
- }
- }
-
- header_line_ok=True; /* information is correct */
- TALLOC_FREE(frame);
- return False; /* need subline info to include into queuelist */
- }
-}
-
-/****************************************************************************
-parse a lpstat line
-
-here is an example of "lpstat -o dcslw" output under sysv
-
-dcslw-896 tridge 4712 Dec 20 10:30:30 on dcslw
-dcslw-897 tridge 4712 Dec 20 10:30:30 being held
-
-****************************************************************************/
-
-static bool parse_lpq_sysv(char *line,print_queue_struct *buf,bool first)
-{
- char *tok[9];
- int count=0;
- char *p;
- const char *cline = line;
- TALLOC_CTX *frame = NULL;
-
- /*
- * Handle the dash in the job id, but make sure that we skip over
- * the printer name in case we have a dash in that.
- * Patch from Dom.Mitchell@palmerharvey.co.uk.
- */
-
- /*
- * Move to the first space.
- */
- for (p = line ; !isspace(*p) && *p; p++) {
- ;
- }
-
- /*
- * Back up until the last '-' character or
- * start of line.
- */
- for (; (p >= line) && (*p != '-'); p--) {
- ;
- }
-
- if((p >= line) && (*p == '-')) {
- *p = ' ';
- }
-
- frame = talloc_stackframe();
- for (count=0; count<9 &&
- next_token_talloc(frame, &cline, &tok[count],NULL);
- count++) {
- ;
- }
-
- /* we must get 7 tokens */
- if (count < 7) {
- TALLOC_FREE(frame);
- return False;
- }
-
- /* the 2nd and 4th, 6th columns must be integer */
- if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[3])) {
- TALLOC_FREE(frame);
- return False;
- }
- if (!isdigit((int)*tok[5])) {
- TALLOC_FREE(frame);
- return False;
- }
-
- /* if the user contains a ! then trim the first part of it */
- if ((p=strchr_m(tok[2],'!'))) {
- tok[2] = p+1;
- }
-
- buf->job = atoi(tok[1]);
- buf->size = atoi(tok[3]);
- if (count > 7 && strequal(tok[7],"on")) {
- buf->status = LPQ_PRINTING;
- } else if (count > 8 && strequal(tok[7],"being") && strequal(tok[8],"held")) {
- buf->status = LPQ_PAUSED;
- } else {
- buf->status = LPQ_QUEUED;
- }
- buf->priority = 0;
- buf->time = EntryTime(tok, 4, count, 7);
- fstrcpy(buf->fs_user,tok[2]);
- fstrcpy(buf->fs_file,tok[2]);
- TALLOC_FREE(frame);
- return True;
-}
-
-/****************************************************************************
-parse a lpq line
-
-here is an example of lpq output under qnx
-Spooler: /qnx/spooler, on node 1
-Printer: txt (ready)
-0000: root [job #1 ] active 1146 bytes /etc/profile
-0001: root [job #2 ] ready 2378 bytes /etc/install
-0002: root [job #3 ] ready 1146 bytes -- standard input --
-****************************************************************************/
-
-static bool parse_lpq_qnx(char *line,print_queue_struct *buf,bool first)
-{
- char *tok[7];
- int count=0;
- const char *cline = line;
- TALLOC_CTX *frame = NULL;
-
- DEBUG(4,("antes [%s]\n", line));
-
- /* handle the case of "-- standard input --" as a filename */
- string_sub(line,"standard input","STDIN",0);
- DEBUG(4,("despues [%s]\n", line));
- all_string_sub(line,"-- ","\"",0);
- all_string_sub(line," --","\"",0);
- DEBUG(4,("despues 1 [%s]\n", line));
-
- string_sub(line,"[job #","",0);
- string_sub(line,"]","",0);
- DEBUG(4,("despues 2 [%s]\n", line));
-
- frame = talloc_stackframe();
- for (count=0; count<7 &&
- next_token_talloc(frame,&cline,&tok[count],NULL);
- count++) {
- ;
- }
-
- /* we must get 7 tokens */
- if (count < 7) {
- TALLOC_FREE(frame);
- return False;
- }
-
- /* the 3rd and 5th columns must be integer */
- if (!isdigit((int)*tok[2]) || !isdigit((int)*tok[4])) {
- TALLOC_FREE(frame);
- return False;
- }
-
- /* only take the last part of the filename */
- {
- char *p = strrchr_m(tok[6],'/');
- if (p) {
- tok[6] = p+1;
- }
- }
-
- buf->job = atoi(tok[2]);
- buf->size = atoi(tok[4]);
- buf->status = strequal(tok[3],"active")?LPQ_PRINTING:LPQ_QUEUED;
- buf->priority = 0;
- buf->time = time(NULL);
- fstrcpy(buf->fs_user,tok[1]);
- fstrcpy(buf->fs_file,tok[6]);
- TALLOC_FREE(frame);
- return True;
-}
-
-/****************************************************************************
- parse a lpq line for the plp printing system
- Bertrand Wallrich <Bertrand.Wallrich@loria.fr>
-
-redone by tridge. Here is a sample queue:
-
-Local Printer 'lp2' (fjall):
- Printing (started at Jun 15 13:33:58, attempt 1).
- Rank Owner Pr Opt Job Host Files Size Date
- active tridge X - 6 fjall /etc/hosts 739 Jun 15 13:33
- 3rd tridge X - 7 fjall /etc/hosts 739 Jun 15 13:33
-
-****************************************************************************/
-
-static bool parse_lpq_plp(char *line,print_queue_struct *buf,bool first)
-{
- char *tok[11];
- int count=0;
- const char *cline = line;
- TALLOC_CTX *frame = talloc_stackframe();
-
- /* handle the case of "(standard input)" as a filename */
- string_sub(line,"stdin","STDIN",0);
- all_string_sub(line,"(","\"",0);
- all_string_sub(line,")","\"",0);
-
- for (count=0; count<11 &&
- next_token_talloc(frame,&cline,&tok[count],NULL);
- count++) {
- ;
- }
-
- /* we must get 11 tokens */
- if (count < 11) {
- TALLOC_FREE(frame);
- return False;
- }
-
- /* the first must be "active" or begin with an integer */
- if (strcmp(tok[0],"active") && !isdigit((int)tok[0][0])) {
- TALLOC_FREE(frame);
- return False;
- }
-
- /* the 5th and 8th must be integer */
- if (!isdigit((int)*tok[4]) || !isdigit((int)*tok[7])) {
- TALLOC_FREE(frame);
- return False;
- }
-
- /* if the fname contains a space then use STDIN */
- if (strchr_m(tok[6],' ')) {
- tok[6] = talloc_strdup(frame, "STDIN");
- if (!tok[6]) {
- TALLOC_FREE(frame);
- return false;
- }
- }
-
- /* only take the last part of the filename */
- {
- fstring tmp;
- char *p = strrchr_m(tok[6],'/');
- if (p) {
- fstrcpy(tmp,p+1);
- fstrcpy(tok[6],tmp);
- }
- }
-
- buf->job = atoi(tok[4]);
-
- buf->size = atoi(tok[7]);
- if (strchr_m(tok[7],'K')) {
- buf->size *= 1024;
- }
- if (strchr_m(tok[7],'M')) {
- buf->size *= 1024*1024;
- }
-
- buf->status = strequal(tok[0],"active")?LPQ_PRINTING:LPQ_QUEUED;
- buf->priority = 0;
- buf->time = time(NULL);
- fstrcpy(buf->fs_user,tok[1]);
- fstrcpy(buf->fs_file,tok[6]);
- TALLOC_FREE(frame);
- return True;
-}
-
-/*******************************************************************
-parse lpq on an NT system
-
- Windows 2000 LPD Server
- Printer \\10.0.0.2\NP17PCL (Paused)
-
-Owner Status Jobname Job-Id Size Pages Priority
-----------------------------------------------------------------------------
-root (9.99. Printing /usr/lib/rhs/rhs-pr 3 625 0 1
-root (9.99. Paused /usr/lib/rhs/rhs-pr 4 625 0 1
-jmcd Waiting Re: Samba Open Sour 26 32476 1 1
-
-********************************************************************/
-
-static bool parse_lpq_nt(char *line,print_queue_struct *buf,bool first)
-{
-#define LPRNT_OWNSIZ 11
-#define LPRNT_STATSIZ 9
-#define LPRNT_JOBSIZ 19
-#define LPRNT_IDSIZ 6
-#define LPRNT_SIZSIZ 9
- typedef struct {
- char owner[LPRNT_OWNSIZ];
- char space1;
- char status[LPRNT_STATSIZ];
- char space2;
- char jobname[LPRNT_JOBSIZ];
- char space3;
- char jobid[LPRNT_IDSIZ];
- char space4;
- char size[LPRNT_SIZSIZ];
- char terminator;
- } nt_lpq_line;
-
- char parse_line_char[sizeof(nt_lpq_line)];
- nt_lpq_line *parse_line = (nt_lpq_line *)parse_line_char;
-#define LPRNT_PRINTING "Printing"
-#define LPRNT_WAITING "Waiting"
-#define LPRNT_PAUSED "Paused"
-
- memset(parse_line_char, '\0', sizeof(parse_line_char));
- strncpy(parse_line_char, line, sizeof(parse_line_char) -1);
-
- if (strlen(parse_line_char) != sizeof(parse_line_char) - 1) {
- return False;
- }
-
- /* Just want the first word in the owner field - the username */
- if (strchr_m(parse_line->owner, ' ')) {
- *(strchr_m(parse_line->owner, ' ')) = '\0';
- } else {
- parse_line->space1 = '\0';
- }
-
- /* Make sure we have an owner */
- if (!strlen(parse_line->owner)) {
- return False;
- }
-
- /* Make sure the status is valid */
- parse_line->space2 = '\0';
- trim_char(parse_line->status, '\0', ' ');
- if (!strequal(parse_line->status, LPRNT_PRINTING) &&
- !strequal(parse_line->status, LPRNT_PAUSED) &&
- !strequal(parse_line->status, LPRNT_WAITING)) {
- return False;
- }
-
- parse_line->space3 = '\0';
- trim_char(parse_line->jobname, '\0', ' ');
-
- buf->job = atoi(parse_line->jobid);
- buf->priority = 0;
- buf->size = atoi(parse_line->size);
- buf->time = time(NULL);
- fstrcpy(buf->fs_user, parse_line->owner);
- fstrcpy(buf->fs_file, parse_line->jobname);
- if (strequal(parse_line->status, LPRNT_PRINTING)) {
- buf->status = LPQ_PRINTING;
- } else if (strequal(parse_line->status, LPRNT_PAUSED)) {
- buf->status = LPQ_PAUSED;
- } else {
- buf->status = LPQ_QUEUED;
- }
-
- return True;
-}
-
-/*******************************************************************
-parse lpq on an OS2 system
-
-JobID File Name Rank Size Status Comment
------ --------------- ------ -------- ------------ ------------
- 3 Control 1 68 Queued root@psflinu
- 4 /etc/motd 2 11666 Queued root@psflinu
-
-********************************************************************/
-
-static bool parse_lpq_os2(char *line,print_queue_struct *buf,bool first)
-{
-#define LPROS2_IDSIZ 5
-#define LPROS2_JOBSIZ 15
-#define LPROS2_SIZSIZ 8
-#define LPROS2_STATSIZ 12
-#define LPROS2_OWNSIZ 12
- typedef struct {
- char jobid[LPROS2_IDSIZ];
- char space1[2];
- char jobname[LPROS2_JOBSIZ];
- char space2[14];
- char size[LPROS2_SIZSIZ];
- char space3[4];
- char status[LPROS2_STATSIZ];
- char space4[4];
- char owner[LPROS2_OWNSIZ];
- char terminator;
- } os2_lpq_line;
-
- char parse_line_char[sizeof(os2_lpq_line)];
- os2_lpq_line *parse_line = (os2_lpq_line *)parse_line_char;
-#define LPROS2_PRINTING "Printing"
-#define LPROS2_WAITING "Queued"
-#define LPROS2_PAUSED "Paused"
-
- memset(parse_line_char, '\0', sizeof(parse_line_char));
- strncpy(parse_line_char, line, sizeof(parse_line_char) -1);
-
- if (strlen(parse_line_char) != sizeof(parse_line_char) - 1) {
- return False;
- }
-
- /* Get the jobid */
- buf->job = atoi(parse_line->jobid);
-
- /* Get the job name */
- parse_line->space2[0] = '\0';
- trim_char(parse_line->jobname, '\0', ' ');
- fstrcpy(buf->fs_file, parse_line->jobname);
-
- buf->priority = 0;
- buf->size = atoi(parse_line->size);
- buf->time = time(NULL);
-
- /* Make sure we have an owner */
- if (!strlen(parse_line->owner)) {
- return False;
- }
-
- /* Make sure we have a valid status */
- parse_line->space4[0] = '\0';
- trim_char(parse_line->status, '\0', ' ');
- if (!strequal(parse_line->status, LPROS2_PRINTING) &&
- !strequal(parse_line->status, LPROS2_PAUSED) &&
- !strequal(parse_line->status, LPROS2_WAITING)) {
- return False;
- }
-
- fstrcpy(buf->fs_user, parse_line->owner);
- if (strequal(parse_line->status, LPROS2_PRINTING)) {
- buf->status = LPQ_PRINTING;
- } else if (strequal(parse_line->status, LPROS2_PAUSED)) {
- buf->status = LPQ_PAUSED;
- } else {
- buf->status = LPQ_QUEUED;
- }
-
- return True;
-}
-
-static const char *stat0_strings[] = { "enabled", "online", "idle", "no entries", "free", "ready", NULL };
-static const char *stat1_strings[] = { "offline", "disabled", "down", "off", "waiting", "no daemon", NULL };
-static const char *stat2_strings[] = { "jam", "paper", "error", "responding", "not accepting", "not running", "turned off", NULL };
-
-#ifdef DEVELOPER
-
-/****************************************************************************
-parse a vlp line
-****************************************************************************/
-
-static bool parse_lpq_vlp(char *line,print_queue_struct *buf,bool first)
-{
- int toknum = 0;
- char *tok;
- TALLOC_CTX *frame = talloc_stackframe();
- const char *cline = line;
-
- /* First line is printer status */
-
- if (!isdigit(line[0])) {
- TALLOC_FREE(frame);
- return False;
- }
-
- /* Parse a print job entry */
-
- while(next_token_talloc(frame, &cline, &tok, NULL)) {
- switch (toknum) {
- case 0:
- buf->job = atoi(tok);
- break;
- case 1:
- buf->size = atoi(tok);
- break;
- case 2:
- buf->status = atoi(tok);
- break;
- case 3:
- buf->time = atoi(tok);
- break;
- case 4:
- fstrcpy(buf->fs_user, tok);
- break;
- case 5:
- fstrcpy(buf->fs_file, tok);
- break;
- }
- toknum++;
- }
-
- TALLOC_FREE(frame);
- return True;
-}
-
-#endif /* DEVELOPER */
-
-/****************************************************************************
-parse a lpq line. Choose printing style
-****************************************************************************/
-
-bool parse_lpq_entry(enum printing_types printing_type,char *line,
- print_queue_struct *buf,
- print_status_struct *status,bool first)
-{
- bool ret;
-
- switch (printing_type) {
- case PRINT_SYSV:
- ret = parse_lpq_sysv(line,buf,first);
- break;
- case PRINT_AIX:
- ret = parse_lpq_aix(line,buf,first);
- break;
- case PRINT_HPUX:
- ret = parse_lpq_hpux(line,buf,first);
- break;
- case PRINT_QNX:
- ret = parse_lpq_qnx(line,buf,first);
- break;
- case PRINT_LPRNG:
- ret = parse_lpq_lprng(line,buf,first);
- break;
- case PRINT_PLP:
- ret = parse_lpq_plp(line,buf,first);
- break;
- case PRINT_LPRNT:
- ret = parse_lpq_nt(line,buf,first);
- break;
- case PRINT_LPROS2:
- ret = parse_lpq_os2(line,buf,first);
- break;
-#ifdef DEVELOPER
- case PRINT_VLP:
- case PRINT_TEST:
- ret = parse_lpq_vlp(line,buf,first);
- break;
-#endif /* DEVELOPER */
- default:
- ret = parse_lpq_bsd(line,buf,first);
- break;
- }
-
- /* We don't want the newline in the status message. */
- {
- char *p = strchr_m(line,'\n');
- if (p) {
- *p = 0;
- }
- }
-
- /* in the LPRNG case, we skip lines starting by a space.*/
- if (!ret && (printing_type==PRINT_LPRNG) ) {
- if (line[0]==' ') {
- return ret;
- }
- }
-
- if (status && !ret) {
- /* a few simple checks to see if the line might be a
- printer status line:
- handle them so that most severe condition is shown */
- int i;
- strlower_m(line);
-
- switch (status->status) {
- case LPSTAT_OK:
- for (i=0; stat0_strings[i]; i++) {
- if (strstr_m(line,stat0_strings[i])) {
- fstrcpy(status->message,line);
- status->status=LPSTAT_OK;
- return ret;
- }
- }
- /* fallthrough */
- case LPSTAT_STOPPED:
- for (i=0; stat1_strings[i]; i++) {
- if (strstr_m(line,stat1_strings[i])) {
- fstrcpy(status->message,line);
- status->status=LPSTAT_STOPPED;
- return ret;
- }
- }
- /* fallthrough */
- case LPSTAT_ERROR:
- for (i=0; stat2_strings[i]; i++) {
- if (strstr_m(line,stat2_strings[i])) {
- fstrcpy(status->message,line);
- status->status=LPSTAT_ERROR;
- return ret;
- }
- }
- break;
- }
- }
-
- return ret;
-}
-
-/****************************************************************************
- Parse a file name from the system spooler to generate a jobid.
-****************************************************************************/
-
-uint32_t print_parse_jobid(const char *fname)
-{
- int jobid;
- const char *p = strstr_m(fname,PRINT_SPOOL_PREFIX);
-
- if (!p) {
- return (uint32_t)-1;
- }
- p += strlen(PRINT_SPOOL_PREFIX);
- jobid = atoi(p);
- if (jobid <= 0) {
- return (uint32_t)-1;
- }
- return (uint32_t)jobid;
-}
+++ /dev/null
-/*
- Unix SMB/Netbios implementation.
- Version 3.0
- printing backend routines
- Copyright (C) Tim Potter, 2002
- Copyright (C) Gerald Carter, 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 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "printing.h"
-
-static TALLOC_CTX *send_ctx;
-
-static unsigned int num_messages;
-
-static struct notify_queue {
- struct notify_queue *next, *prev;
- struct spoolss_notify_msg *msg;
- struct timeval tv;
- uint8 *buf;
- size_t buflen;
-} *notify_queue_head = NULL;
-
-static struct tevent_timer *notify_event;
-
-static bool print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx,
- size_t *p_num_pids, pid_t **pp_pid_list);
-
-static bool create_send_ctx(void)
-{
- if (!send_ctx)
- send_ctx = talloc_init("print notify queue");
-
- if (!send_ctx)
- return False;
-
- return True;
-}
-
-/****************************************************************************
- Turn a queue name into a snum.
-****************************************************************************/
-
-int print_queue_snum(const char *qname)
-{
- int snum = lp_servicenumber(qname);
- if (snum == -1 || !lp_print_ok(snum))
- return -1;
- return snum;
-}
-
-/*******************************************************************
- Used to decide if we need a short select timeout.
-*******************************************************************/
-
-static bool print_notify_messages_pending(void)
-{
- return (notify_queue_head != NULL);
-}
-
-/*******************************************************************
- Flatten data into a message.
-*******************************************************************/
-
-static bool flatten_message(struct notify_queue *q)
-{
- struct spoolss_notify_msg *msg = q->msg;
- uint8 *buf = NULL;
- size_t buflen = 0, len;
-
-again:
- len = 0;
-
- /* Pack header */
-
- len += tdb_pack(buf + len, buflen - len, "f", msg->printer);
-
- len += tdb_pack(buf + len, buflen - len, "ddddddd",
- (uint32)q->tv.tv_sec, (uint32)q->tv.tv_usec,
- msg->type, msg->field, msg->id, msg->len, msg->flags);
-
- /* Pack data */
-
- if (msg->len == 0)
- len += tdb_pack(buf + len, buflen - len, "dd",
- msg->notify.value[0], msg->notify.value[1]);
- else
- len += tdb_pack(buf + len, buflen - len, "B",
- msg->len, msg->notify.data);
-
- if (buflen != len) {
- buf = (uint8 *)TALLOC_REALLOC(send_ctx, buf, len);
- if (!buf)
- return False;
- buflen = len;
- goto again;
- }
-
- q->buf = buf;
- q->buflen = buflen;
-
- return True;
-}
-
-/*******************************************************************
- Send the batched messages - on a per-printer basis.
-*******************************************************************/
-
-static void print_notify_send_messages_to_printer(struct messaging_context *msg_ctx,
- const char *printer,
- unsigned int timeout)
-{
- char *buf;
- struct notify_queue *pq, *pq_next;
- size_t msg_count = 0, offset = 0;
- size_t num_pids = 0;
- size_t i;
- pid_t *pid_list = NULL;
- struct timeval end_time = timeval_zero();
-
- /* Count the space needed to send the messages. */
- for (pq = notify_queue_head; pq; pq = pq->next) {
- if (strequal(printer, pq->msg->printer)) {
- if (!flatten_message(pq)) {
- DEBUG(0,("print_notify_send_messages: Out of memory\n"));
- talloc_free_children(send_ctx);
- num_messages = 0;
- return;
- }
- offset += (pq->buflen + 4);
- msg_count++;
- }
- }
- offset += 4; /* For count. */
-
- buf = (char *)TALLOC(send_ctx, offset);
- if (!buf) {
- DEBUG(0,("print_notify_send_messages: Out of memory\n"));
- talloc_free_children(send_ctx);
- num_messages = 0;
- return;
- }
-
- offset = 0;
- SIVAL(buf,offset,msg_count);
- offset += 4;
- for (pq = notify_queue_head; pq; pq = pq_next) {
- pq_next = pq->next;
-
- if (strequal(printer, pq->msg->printer)) {
- SIVAL(buf,offset,pq->buflen);
- offset += 4;
- memcpy(buf + offset, pq->buf, pq->buflen);
- offset += pq->buflen;
-
- /* Remove from list. */
- DLIST_REMOVE(notify_queue_head, pq);
- }
- }
-
- DEBUG(5, ("print_notify_send_messages_to_printer: sending %lu print notify message%s to printer %s\n",
- (unsigned long)msg_count, msg_count != 1 ? "s" : "", printer));
-
- /*
- * Get the list of PID's to send to.
- */
-
- if (!print_notify_pid_list(printer, send_ctx, &num_pids, &pid_list))
- return;
-
- if (timeout != 0) {
- end_time = timeval_current_ofs(timeout, 0);
- }
-
- for (i = 0; i < num_pids; i++) {
- messaging_send_buf(msg_ctx,
- pid_to_procid(pid_list[i]),
- MSG_PRINTER_NOTIFY2 | MSG_FLAG_LOWPRIORITY,
- (uint8 *)buf, offset);
-
- if ((timeout != 0) && timeval_expired(&end_time)) {
- break;
- }
- }
-}
-
-/*******************************************************************
- Actually send the batched messages.
-*******************************************************************/
-
-void print_notify_send_messages(struct messaging_context *msg_ctx,
- unsigned int timeout)
-{
- if (!print_notify_messages_pending())
- return;
-
- if (!create_send_ctx())
- return;
-
- while (print_notify_messages_pending())
- print_notify_send_messages_to_printer(
- msg_ctx, notify_queue_head->msg->printer, timeout);
-
- talloc_free_children(send_ctx);
- num_messages = 0;
-}
-
-/*******************************************************************
- Event handler to send the messages.
-*******************************************************************/
-
-static void print_notify_event_send_messages(struct tevent_context *event_ctx,
- struct tevent_timer *te,
- struct timeval now,
- void *private_data)
-{
- /* Remove this timed event handler. */
- TALLOC_FREE(notify_event);
-
- change_to_root_user();
- print_notify_send_messages(smbd_messaging_context(), 0);
-}
-
-/**********************************************************************
- deep copy a SPOOLSS_NOTIFY_MSG structure using a TALLOC_CTX
- *********************************************************************/
-
-static bool copy_notify2_msg( SPOOLSS_NOTIFY_MSG *to, SPOOLSS_NOTIFY_MSG *from )
-{
-
- if ( !to || !from )
- return False;
-
- memcpy( to, from, sizeof(SPOOLSS_NOTIFY_MSG) );
-
- if ( from->len ) {
- to->notify.data = (char *)TALLOC_MEMDUP(send_ctx, from->notify.data, from->len );
- if ( !to->notify.data ) {
- DEBUG(0,("copy_notify2_msg: TALLOC_MEMDUP() of size [%d] failed!\n", from->len ));
- return False;
- }
- }
-
-
- return True;
-}
-
-/*******************************************************************
- Batch up print notify messages.
-*******************************************************************/
-
-static void send_spoolss_notify2_msg(SPOOLSS_NOTIFY_MSG *msg)
-{
- struct notify_queue *pnqueue, *tmp_ptr;
-
- /*
- * Ensure we only have one job total_bytes and job total_pages for
- * each job. There is no point in sending multiple messages that match
- * as they will just cause flickering updates in the client.
- */
-
- if ((num_messages < 100) && (msg->type == JOB_NOTIFY_TYPE)
- && (msg->field == JOB_NOTIFY_FIELD_TOTAL_BYTES
- || msg->field == JOB_NOTIFY_FIELD_TOTAL_PAGES ))
- {
-
- for (tmp_ptr = notify_queue_head; tmp_ptr; tmp_ptr = tmp_ptr->next)
- {
- if (tmp_ptr->msg->type == msg->type &&
- tmp_ptr->msg->field == msg->field &&
- tmp_ptr->msg->id == msg->id &&
- tmp_ptr->msg->flags == msg->flags &&
- strequal(tmp_ptr->msg->printer, msg->printer)) {
-
- DEBUG(5,("send_spoolss_notify2_msg: replacing message 0x%02x/0x%02x for "
- "printer %s in notify_queue\n", msg->type, msg->field, msg->printer));
-
- tmp_ptr->msg = msg;
- return;
- }
- }
- }
-
- /* Store the message on the pending queue. */
-
- pnqueue = TALLOC_P(send_ctx, struct notify_queue);
- if (!pnqueue) {
- DEBUG(0,("send_spoolss_notify2_msg: Out of memory.\n"));
- return;
- }
-
- /* allocate a new msg structure and copy the fields */
-
- if ( !(pnqueue->msg = TALLOC_P(send_ctx, SPOOLSS_NOTIFY_MSG)) ) {
- DEBUG(0,("send_spoolss_notify2_msg: talloc() of size [%lu] failed!\n",
- (unsigned long)sizeof(SPOOLSS_NOTIFY_MSG)));
- return;
- }
- copy_notify2_msg(pnqueue->msg, msg);
- GetTimeOfDay(&pnqueue->tv);
- pnqueue->buf = NULL;
- pnqueue->buflen = 0;
-
- DEBUG(5, ("send_spoolss_notify2_msg: appending message 0x%02x/0x%02x for printer %s \
-to notify_queue_head\n", msg->type, msg->field, msg->printer));
-
- /*
- * Note we add to the end of the list to ensure
- * the messages are sent in the order they were received. JRA.
- */
-
- DLIST_ADD_END(notify_queue_head, pnqueue, struct notify_queue *);
- num_messages++;
-
- if ((notify_event == NULL) && (smbd_event_context() != NULL)) {
- /* Add an event for 1 second's time to send this queue. */
- notify_event = tevent_add_timer(smbd_event_context(), NULL,
- timeval_current_ofs(1,0),
- print_notify_event_send_messages, NULL);
- }
-
-}
-
-static void send_notify_field_values(const char *sharename, uint32 type,
- uint32 field, uint32 id, uint32 value1,
- uint32 value2, uint32 flags)
-{
- struct spoolss_notify_msg *msg;
-
- if (lp_disable_spoolss())
- return;
-
- if (!create_send_ctx())
- return;
-
- msg = TALLOC_P(send_ctx, struct spoolss_notify_msg);
- if (!msg)
- return;
-
- ZERO_STRUCTP(msg);
-
- fstrcpy(msg->printer, sharename);
- msg->type = type;
- msg->field = field;
- msg->id = id;
- msg->notify.value[0] = value1;
- msg->notify.value[1] = value2;
- msg->flags = flags;
-
- send_spoolss_notify2_msg(msg);
-}
-
-static void send_notify_field_buffer(const char *sharename, uint32 type,
- uint32 field, uint32 id, uint32 len,
- const char *buffer)
-{
- struct spoolss_notify_msg *msg;
-
- if (lp_disable_spoolss())
- return;
-
- if (!create_send_ctx())
- return;
-
- msg = TALLOC_P(send_ctx, struct spoolss_notify_msg);
- if (!msg)
- return;
-
- ZERO_STRUCTP(msg);
-
- fstrcpy(msg->printer, sharename);
- msg->type = type;
- msg->field = field;
- msg->id = id;
- msg->len = len;
- msg->notify.data = CONST_DISCARD(char *,buffer);
-
- send_spoolss_notify2_msg(msg);
-}
-
-/* Send a message that the printer status has changed */
-
-void notify_printer_status_byname(const char *sharename, uint32 status)
-{
- /* Printer status stored in value1 */
-
- int snum = print_queue_snum(sharename);
-
- send_notify_field_values(sharename, PRINTER_NOTIFY_TYPE,
- PRINTER_NOTIFY_FIELD_STATUS, snum,
- status, 0, 0);
-}
-
-void notify_printer_status(int snum, uint32 status)
-{
- const char *sharename = SERVICE(snum);
-
- if (sharename)
- notify_printer_status_byname(sharename, status);
-}
-
-void notify_job_status_byname(const char *sharename, uint32 jobid, uint32 status,
- uint32 flags)
-{
- /* Job id stored in id field, status in value1 */
-
- send_notify_field_values(sharename, JOB_NOTIFY_TYPE,
- JOB_NOTIFY_FIELD_STATUS, jobid,
- status, 0, flags);
-}
-
-void notify_job_status(const char *sharename, uint32 jobid, uint32 status)
-{
- notify_job_status_byname(sharename, jobid, status, 0);
-}
-
-void notify_job_total_bytes(const char *sharename, uint32 jobid,
- uint32 size)
-{
- /* Job id stored in id field, status in value1 */
-
- send_notify_field_values(sharename, JOB_NOTIFY_TYPE,
- JOB_NOTIFY_FIELD_TOTAL_BYTES, jobid,
- size, 0, 0);
-}
-
-void notify_job_total_pages(const char *sharename, uint32 jobid,
- uint32 pages)
-{
- /* Job id stored in id field, status in value1 */
-
- send_notify_field_values(sharename, JOB_NOTIFY_TYPE,
- JOB_NOTIFY_FIELD_TOTAL_PAGES, jobid,
- pages, 0, 0);
-}
-
-void notify_job_username(const char *sharename, uint32 jobid, char *name)
-{
- send_notify_field_buffer(
- sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME,
- jobid, strlen(name) + 1, name);
-}
-
-void notify_job_name(const char *sharename, uint32 jobid, char *name)
-{
- send_notify_field_buffer(
- sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT,
- jobid, strlen(name) + 1, name);
-}
-
-void notify_job_submitted(const char *sharename, uint32 jobid,
- time_t submitted)
-{
- send_notify_field_buffer(
- sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED,
- jobid, sizeof(submitted), (char *)&submitted);
-}
-
-void notify_printer_driver(int snum, char *driver_name)
-{
- const char *sharename = SERVICE(snum);
-
- send_notify_field_buffer(
- sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME,
- snum, strlen(driver_name) + 1, driver_name);
-}
-
-void notify_printer_comment(int snum, char *comment)
-{
- const char *sharename = SERVICE(snum);
-
- send_notify_field_buffer(
- sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT,
- snum, strlen(comment) + 1, comment);
-}
-
-void notify_printer_sharename(int snum, char *share_name)
-{
- const char *sharename = SERVICE(snum);
-
- send_notify_field_buffer(
- sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME,
- snum, strlen(share_name) + 1, share_name);
-}
-
-void notify_printer_printername(int snum, char *printername)
-{
- const char *sharename = SERVICE(snum);
-
- send_notify_field_buffer(
- sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME,
- snum, strlen(printername) + 1, printername);
-}
-
-void notify_printer_port(int snum, char *port_name)
-{
- const char *sharename = SERVICE(snum);
-
- send_notify_field_buffer(
- sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME,
- snum, strlen(port_name) + 1, port_name);
-}
-
-void notify_printer_location(int snum, char *location)
-{
- const char *sharename = SERVICE(snum);
-
- send_notify_field_buffer(
- sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION,
- snum, strlen(location) + 1, location);
-}
-
-void notify_printer_byname( const char *printername, uint32 change, const char *value )
-{
- int snum = print_queue_snum(printername);
- int type = PRINTER_NOTIFY_TYPE;
-
- if ( snum == -1 )
- return;
-
- send_notify_field_buffer( printername, type, change, snum, strlen(value)+1, value );
-}
-
-
-/****************************************************************************
- Return a malloced list of pid_t's that are interested in getting update
- messages on this print queue. Used in printing/notify to send the messages.
-****************************************************************************/
-
-static bool print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx,
- size_t *p_num_pids, pid_t **pp_pid_list)
-{
- struct tdb_print_db *pdb = NULL;
- TDB_CONTEXT *tdb = NULL;
- TDB_DATA data;
- bool ret = True;
- size_t i, num_pids, offset;
- pid_t *pid_list;
-
- *p_num_pids = 0;
- *pp_pid_list = NULL;
-
- pdb = get_print_db_byname(printername);
- if (!pdb)
- return False;
- tdb = pdb->tdb;
-
- if (tdb_read_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
- DEBUG(0,("print_notify_pid_list: Failed to lock printer %s database\n",
- printername));
- if (pdb)
- release_print_db(pdb);
- return False;
- }
-
- data = get_printer_notify_pid_list( tdb, printername, True );
-
- if (!data.dptr) {
- ret = True;
- goto done;
- }
-
- num_pids = data.dsize / 8;
-
- if (num_pids) {
- if ((pid_list = TALLOC_ARRAY(mem_ctx, pid_t, num_pids)) == NULL) {
- ret = False;
- goto done;
- }
- } else {
- pid_list = NULL;
- }
-
- for( i = 0, offset = 0; i < num_pids; offset += 8, i++)
- pid_list[i] = (pid_t)IVAL(data.dptr, offset);
-
- *pp_pid_list = pid_list;
- *p_num_pids = num_pids;
-
- ret = True;
-
- done:
-
- tdb_read_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
- if (pdb)
- release_print_db(pdb);
- SAFE_FREE(data.dptr);
- return ret;
-}
+++ /dev/null
-/*
- * Unix SMB/CIFS implementation.
- * RPC Pipe client / server routines
- * Copyright (C) Andrew Tridgell 1992-2000,
- * Copyright (C) Jean François Micouleau 1998-2000.
- * Copyright (C) Gerald Carter 2002-2005.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "includes.h"
-
-static TDB_CONTEXT *tdb_forms; /* used for forms files */
-static TDB_CONTEXT *tdb_drivers; /* used for driver files */
-static TDB_CONTEXT *tdb_printers; /* used for printers files */
-
-#define FORMS_PREFIX "FORMS/"
-#define DRIVERS_PREFIX "DRIVERS/"
-#define DRIVER_INIT_PREFIX "DRIVER_INIT/"
-#define PRINTERS_PREFIX "PRINTERS/"
-#define SECDESC_PREFIX "SECDESC/"
-#define GLOBAL_C_SETPRINTER "GLOBALS/c_setprinter"
-
-#define NTDRIVERS_DATABASE_VERSION_1 1
-#define NTDRIVERS_DATABASE_VERSION_2 2
-#define NTDRIVERS_DATABASE_VERSION_3 3 /* little endian version of v2 */
-#define NTDRIVERS_DATABASE_VERSION_4 4 /* fix generic bits in security descriptors */
-#define NTDRIVERS_DATABASE_VERSION_5 5 /* normalize keys in ntprinters.tdb */
-
-/* Map generic permissions to printer object specific permissions */
-
-const struct generic_mapping printer_generic_mapping = {
- PRINTER_READ,
- PRINTER_WRITE,
- PRINTER_EXECUTE,
- PRINTER_ALL_ACCESS
-};
-
-const struct standard_mapping printer_std_mapping = {
- PRINTER_READ,
- PRINTER_WRITE,
- PRINTER_EXECUTE,
- PRINTER_ALL_ACCESS
-};
-
-/* Map generic permissions to print server object specific permissions */
-
-const struct generic_mapping printserver_generic_mapping = {
- SERVER_READ,
- SERVER_WRITE,
- SERVER_EXECUTE,
- SERVER_ALL_ACCESS
-};
-
-const struct generic_mapping printserver_std_mapping = {
- SERVER_READ,
- SERVER_WRITE,
- SERVER_EXECUTE,
- SERVER_ALL_ACCESS
-};
-
-/* Map generic permissions to job object specific permissions */
-
-const struct generic_mapping job_generic_mapping = {
- JOB_READ,
- JOB_WRITE,
- JOB_EXECUTE,
- JOB_ALL_ACCESS
-};
-
-/* We need one default form to support our default printer. Msoft adds the
-forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
-array index). Letter is always first, so (for the current code) additions
-always put things in the correct order. */
-static const nt_forms_struct default_forms[] = {
- {"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
- {"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
- {"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
- {"Ledger",0x1,0x696b8,0x44368,0x0,0x0,0x696b8,0x44368},
- {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
- {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
- {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
- {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
- {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
- {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
- {"A5",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
- {"B4 (JIS)",0x1,0x3ebe8,0x58de0,0x0,0x0,0x3ebe8,0x58de0},
- {"B5 (JIS)",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
- {"Folio",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
- {"Quarto",0x1,0x347d8,0x43238,0x0,0x0,0x347d8,0x43238},
- {"10x14",0x1,0x3e030,0x56d10,0x0,0x0,0x3e030,0x56d10},
- {"11x17",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
- {"Note",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
- {"Envelope #9",0x1,0x18079,0x37091,0x0,0x0,0x18079,0x37091},
- {"Envelope #10",0x1,0x19947,0x3ae94,0x0,0x0,0x19947,0x3ae94},
- {"Envelope #11",0x1,0x1be7c,0x40565,0x0,0x0,0x1be7c,0x40565},
- {"Envelope #12",0x1,0x1d74a,0x44368,0x0,0x0,0x1d74a,0x44368},
- {"Envelope #14",0x1,0x1f018,0x47504,0x0,0x0,0x1f018,0x47504},
- {"C size sheet",0x1,0x696b8,0x886d0,0x0,0x0,0x696b8,0x886d0},
- {"D size sheet",0x1,0x886d0,0xd2d70,0x0,0x0,0x886d0,0xd2d70},
- {"E size sheet",0x1,0xd2d70,0x110da0,0x0,0x0,0xd2d70,0x110da0},
- {"Envelope DL",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
- {"Envelope C5",0x1,0x278d0,0x37e88,0x0,0x0,0x278d0,0x37e88},
- {"Envelope C3",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
- {"Envelope C4",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
- {"Envelope C6",0x1,0x1bd50,0x278d0,0x0,0x0,0x1bd50,0x278d0},
- {"Envelope C65",0x1,0x1bd50,0x37e88,0x0,0x0,0x1bd50,0x37e88},
- {"Envelope B4",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
- {"Envelope B5",0x1,0x2af80,0x3d090,0x0,0x0,0x2af80,0x3d090},
- {"Envelope B6",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
- {"Envelope",0x1,0x1adb0,0x38270,0x0,0x0,0x1adb0,0x38270},
- {"Envelope Monarch",0x1,0x18079,0x2e824,0x0,0x0,0x18079,0x2e824},
- {"6 3/4 Envelope",0x1,0x167ab,0x284ec,0x0,0x0,0x167ab,0x284ec},
- {"US Std Fanfold",0x1,0x5c3e1,0x44368,0x0,0x0,0x5c3e1,0x44368},
- {"German Std Fanfold",0x1,0x34b5c,0x4a6a0,0x0,0x0,0x34b5c,0x4a6a0},
- {"German Legal Fanfold",0x1,0x34b5c,0x509d8,0x0,0x0,0x34b5c,0x509d8},
- {"B4 (ISO)",0x1,0x3d090,0x562e8,0x0,0x0,0x3d090,0x562e8},
- {"Japanese Postcard",0x1,0x186a0,0x24220,0x0,0x0,0x186a0,0x24220},
- {"9x11",0x1,0x37cf8,0x44368,0x0,0x0,0x37cf8,0x44368},
- {"10x11",0x1,0x3e030,0x44368,0x0,0x0,0x3e030,0x44368},
- {"15x11",0x1,0x5d048,0x44368,0x0,0x0,0x5d048,0x44368},
- {"Envelope Invite",0x1,0x35b60,0x35b60,0x0,0x0,0x35b60,0x35b60},
- {"Reserved48",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
- {"Reserved49",0x1,0x1,0x1,0x0,0x0,0x1,0x1},
- {"Letter Extra",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
- {"Legal Extra",0x1,0x3ae94,0x5d048,0x0,0x0,0x3ae94,0x5d048},
- {"Tabloid Extra",0x1,0x4a6a0,0x6f9f0,0x0,0x0,0x4a6a0,0x6f9f0},
- {"A4 Extra",0x1,0x397c2,0x4eb16,0x0,0x0,0x397c2,0x4eb16},
- {"Letter Transverse",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
- {"A4 Transverse",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
- {"Letter Extra Transverse",0x1,0x3ae94,0x4a6a0,0x0,0x0,0x3ae94,0x4a6a0},
- {"Super A",0x1,0x376b8,0x56ea0,0x0,0x0,0x376b8,0x56ea0},
- {"Super B",0x1,0x4a768,0x76e58,0x0,0x0,0x4a768,0x76e58},
- {"Letter Plus",0x1,0x34b5c,0x4eb16,0x0,0x0,0x34b5c,0x4eb16},
- {"A4 Plus",0x1,0x33450,0x50910,0x0,0x0,0x33450,0x50910},
- {"A5 Transverse",0x1,0x24220,0x33450,0x0,0x0,0x24220,0x33450},
- {"B5 (JIS) Transverse",0x1,0x2c6f0,0x3ebe8,0x0,0x0,0x2c6f0,0x3ebe8},
- {"A3 Extra",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
- {"A5 Extra",0x1,0x2a7b0,0x395f8,0x0,0x0,0x2a7b0,0x395f8},
- {"B5 (ISO) Extra",0x1,0x31128,0x43620,0x0,0x0,0x31128,0x43620},
- {"A2",0x1,0x668a0,0x91050,0x0,0x0,0x668a0,0x91050},
- {"A3 Transverse",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
- {"A3 Extra Transverse",0x1,0x4e9d0,0x6ca48,0x0,0x0,0x4e9d0,0x6ca48},
- {"Japanese Double Postcard",0x1,0x30d40,0x24220,0x0,0x0,0x30d40,0x24220},
- {"A6",0x1,0x19a28,0x24220,0x0,0x0,0x19a28,0x24220},
- {"Japanese Envelope Kaku #2",0x1,0x3a980,0x510e0,0x0,0x0,0x3a980,0x510e0},
- {"Japanese Envelope Kaku #3",0x1,0x34bc0,0x43a08,0x0,0x0,0x34bc0,0x43a08},
- {"Japanese Envelope Chou #3",0x1,0x1d4c0,0x395f8,0x0,0x0,0x1d4c0,0x395f8},
- {"Japanese Envelope Chou #4",0x1,0x15f90,0x320c8,0x0,0x0,0x15f90,0x320c8},
- {"Letter Rotated",0x1,0x44368,0x34b5c,0x0,0x0,0x44368,0x34b5c},
- {"A3 Rotated",0x1,0x668a0,0x48828,0x0,0x0,0x668a0,0x48828},
- {"A4 Rotated",0x1,0x48828,0x33450,0x0,0x0,0x48828,0x33450},
- {"A5 Rotated",0x1,0x33450,0x24220,0x0,0x0,0x33450,0x24220},
- {"B4 (JIS) Rotated",0x1,0x58de0,0x3ebe8,0x0,0x0,0x58de0,0x3ebe8},
- {"B5 (JIS) Rotated",0x1,0x3ebe8,0x2c6f0,0x0,0x0,0x3ebe8,0x2c6f0},
- {"Japanese Postcard Rotated",0x1,0x24220,0x186a0,0x0,0x0,0x24220,0x186a0},
- {"Double Japan Postcard Rotated",0x1,0x24220,0x30d40,0x0,0x0,0x24220,0x30d40},
- {"A6 Rotated",0x1,0x24220,0x19a28,0x0,0x0,0x24220,0x19a28},
- {"Japan Envelope Kaku #2 Rotated",0x1,0x510e0,0x3a980,0x0,0x0,0x510e0,0x3a980},
- {"Japan Envelope Kaku #3 Rotated",0x1,0x43a08,0x34bc0,0x0,0x0,0x43a08, 0x34bc0},
- {"Japan Envelope Chou #3 Rotated",0x1,0x395f8,0x1d4c0,0x0,0x0,0x395f8,0x1d4c0},
- {"Japan Envelope Chou #4 Rotated",0x1,0x320c8,0x15f90,0x0,0x0,0x320c8,0x15f90},
- {"B6 (JIS)",0x1,0x1f400,0x2c6f0,0x0,0x0,0x1f400,0x2c6f0},
- {"B6 (JIS) Rotated",0x1,0x2c6f0,0x1f400,0x0,0x0,0x2c6f0,0x1f400},
- {"12x11",0x1,0x4a724,0x443e1,0x0,0x0,0x4a724,0x443e1},
- {"Japan Envelope You #4",0x1,0x19a28,0x395f8,0x0,0x0,0x19a28,0x395f8},
- {"Japan Envelope You #4 Rotated",0x1,0x395f8,0x19a28,0x0,0x0,0x395f8,0x19a28},
- {"PRC 16K",0x1,0x2de60,0x3f7a0,0x0,0x0,0x2de60,0x3f7a0},
- {"PRC 32K",0x1,0x1fbd0,0x2cec0,0x0,0x0,0x1fbd0,0x2cec0},
- {"PRC 32K(Big)",0x1,0x222e0,0x318f8,0x0,0x0,0x222e0,0x318f8},
- {"PRC Envelope #1",0x1,0x18e70,0x28488,0x0,0x0,0x18e70,0x28488},
- {"PRC Envelope #2",0x1,0x18e70,0x2af80,0x0,0x0,0x18e70,0x2af80},
- {"PRC Envelope #3",0x1,0x1e848,0x2af80,0x0,0x0,0x1e848,0x2af80},
- {"PRC Envelope #4",0x1,0x1adb0,0x32c80,0x0,0x0,0x1adb0,0x32c80},
- {"PRC Envelope #5",0x1,0x1adb0,0x35b60,0x0,0x0,0x1adb0,0x35b60},
- {"PRC Envelope #6",0x1,0x1d4c0,0x38270,0x0,0x0,0x1d4c0,0x38270},
- {"PRC Envelope #7",0x1,0x27100,0x38270,0x0,0x0,0x27100,0x38270},
- {"PRC Envelope #8",0x1,0x1d4c0,0x4b708,0x0,0x0,0x1d4c0,0x4b708},
- {"PRC Envelope #9",0x1,0x37e88,0x4f1a0,0x0,0x0,0x37e88,0x4f1a0},
- {"PRC Envelope #10",0x1,0x4f1a0,0x6fd10,0x0,0x0,0x4f1a0,0x6fd10},
- {"PRC 16K Rotated",0x1,0x3f7a0,0x2de60,0x0,0x0,0x3f7a0,0x2de60},
- {"PRC 32K Rotated",0x1,0x2cec0,0x1fbd0,0x0,0x0,0x2cec0,0x1fbd0},
- {"PRC 32K(Big) Rotated",0x1,0x318f8,0x222e0,0x0,0x0,0x318f8,0x222e0},
- {"PRC Envelope #1 Rotated",0x1,0x28488,0x18e70,0x0,0x0,0x28488,0x18e70},
- {"PRC Envelope #2 Rotated",0x1,0x2af80,0x18e70,0x0,0x0,0x2af80,0x18e70},
- {"PRC Envelope #3 Rotated",0x1,0x2af80,0x1e848,0x0,0x0,0x2af80,0x1e848},
- {"PRC Envelope #4 Rotated",0x1,0x32c80,0x1adb0,0x0,0x0,0x32c80,0x1adb0},
- {"PRC Envelope #5 Rotated",0x1,0x35b60,0x1adb0,0x0,0x0,0x35b60,0x1adb0},
- {"PRC Envelope #6 Rotated",0x1,0x38270,0x1d4c0,0x0,0x0,0x38270,0x1d4c0},
- {"PRC Envelope #7 Rotated",0x1,0x38270,0x27100,0x0,0x0,0x38270,0x27100},
- {"PRC Envelope #8 Rotated",0x1,0x4b708,0x1d4c0,0x0,0x0,0x4b708,0x1d4c0},
- {"PRC Envelope #9 Rotated",0x1,0x4f1a0,0x37e88,0x0,0x0,0x4f1a0,0x37e88},
- {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
-};
-
-static const struct print_architecture_table_node archi_table[]= {
-
- {"Windows 4.0", SPL_ARCH_WIN40, 0 },
- {"Windows NT x86", SPL_ARCH_W32X86, 2 },
- {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
- {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
- {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
- {"Windows IA64", SPL_ARCH_IA64, 3 },
- {"Windows x64", SPL_ARCH_X64, 3 },
- {NULL, "", -1 }
-};
-
-
-/****************************************************************************
- generate a new TDB_DATA key for storing a printer
-****************************************************************************/
-
-static TDB_DATA make_printer_tdbkey(TALLOC_CTX *ctx, const char *sharename )
-{
- fstring share;
- char *keystr = NULL;
- TDB_DATA key;
-
- fstrcpy(share, sharename);
- strlower_m(share);
-
- keystr = talloc_asprintf(ctx, "%s%s", PRINTERS_PREFIX, share);
- key = string_term_tdb_data(keystr ? keystr : "");
-
- return key;
-}
-
-/****************************************************************************
- generate a new TDB_DATA key for storing a printer security descriptor
-****************************************************************************/
-
-static TDB_DATA make_printers_secdesc_tdbkey(TALLOC_CTX *ctx,
- const char* sharename )
-{
- fstring share;
- char *keystr = NULL;
- TDB_DATA key;
-
- fstrcpy(share, sharename );
- strlower_m(share);
-
- keystr = talloc_asprintf(ctx, "%s%s", SECDESC_PREFIX, share);
- key = string_term_tdb_data(keystr ? keystr : "");
-
- return key;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static bool upgrade_to_version_3(void)
-{
- TDB_DATA kbuf, newkey, dbuf;
-
- DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
-
- for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
- newkey = tdb_nextkey(tdb_drivers, kbuf), free(kbuf.dptr), kbuf=newkey) {
-
- dbuf = tdb_fetch(tdb_drivers, kbuf);
-
- if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
- DEBUG(0,("upgrade_to_version_3:moving form\n"));
- if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
- SAFE_FREE(dbuf.dptr);
- DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
- return False;
- }
- if (tdb_delete(tdb_drivers, kbuf) != 0) {
- SAFE_FREE(dbuf.dptr);
- DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
- return False;
- }
- }
-
- if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
- DEBUG(0,("upgrade_to_version_3:moving printer\n"));
- if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
- SAFE_FREE(dbuf.dptr);
- DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
- return False;
- }
- if (tdb_delete(tdb_drivers, kbuf) != 0) {
- SAFE_FREE(dbuf.dptr);
- DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
- return False;
- }
- }
-
- if (strncmp((const char *)kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
- DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
- if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
- SAFE_FREE(dbuf.dptr);
- DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
- return False;
- }
- if (tdb_delete(tdb_drivers, kbuf) != 0) {
- SAFE_FREE(dbuf.dptr);
- DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
- return False;
- }
- }
-
- SAFE_FREE(dbuf.dptr);
- }
-
- return True;
-}
-
-/*******************************************************************
- Fix an issue with security descriptors. Printer sec_desc must
- use more than the generic bits that were previously used
- in <= 3.0.14a. They must also have a owner and group SID assigned.
- Otherwise, any printers than have been migrated to a Windows
- host using printmig.exe will not be accessible.
-*******************************************************************/
-
-static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
- TDB_DATA data, void *state )
-{
- NTSTATUS status;
- SEC_DESC_BUF *sd_orig = NULL;
- SEC_DESC_BUF *sd_new, *sd_store;
- SEC_DESC *sec, *new_sec;
- TALLOC_CTX *ctx = state;
- int result, i;
- uint32 sd_size;
- size_t size_new_sec;
-
- if (!data.dptr || data.dsize == 0) {
- return 0;
- }
-
- if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) != 0 ) {
- return 0;
- }
-
- /* upgrade the security descriptor */
-
- status = unmarshall_sec_desc_buf(ctx, data.dptr, data.dsize, &sd_orig);
- if (!NT_STATUS_IS_OK(status)) {
- /* delete bad entries */
- DEBUG(0,("sec_desc_upg_fn: Failed to parse original sec_desc for %si. Deleting....\n",
- (const char *)key.dptr ));
- tdb_delete( tdb_printers, key );
- return 0;
- }
-
- if (!sd_orig) {
- return 0;
- }
- sec = sd_orig->sd;
-
- /* is this even valid? */
-
- if ( !sec->dacl ) {
- return 0;
- }
-
- /* update access masks */
-
- for ( i=0; i<sec->dacl->num_aces; i++ ) {
- switch ( sec->dacl->aces[i].access_mask ) {
- case (GENERIC_READ_ACCESS | GENERIC_WRITE_ACCESS | GENERIC_EXECUTE_ACCESS):
- sec->dacl->aces[i].access_mask = PRINTER_ACE_PRINT;
- break;
-
- case GENERIC_ALL_ACCESS:
- sec->dacl->aces[i].access_mask = PRINTER_ACE_FULL_CONTROL;
- break;
-
- case READ_CONTROL_ACCESS:
- sec->dacl->aces[i].access_mask = PRINTER_ACE_MANAGE_DOCUMENTS;
-
- default: /* no change */
- break;
- }
- }
-
- /* create a new SEC_DESC with the appropriate owner and group SIDs */
-
- new_sec = make_sec_desc( ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
- &global_sid_Builtin_Administrators,
- &global_sid_Builtin_Administrators,
- NULL, NULL, &size_new_sec );
- if (!new_sec) {
- return 0;
- }
- sd_new = make_sec_desc_buf( ctx, size_new_sec, new_sec );
- if (!sd_new) {
- return 0;
- }
-
- if ( !(sd_store = sec_desc_merge( ctx, sd_new, sd_orig )) ) {
- DEBUG(0,("sec_desc_upg_fn: Failed to update sec_desc for %s\n", key.dptr ));
- return 0;
- }
-
- /* store it back */
-
- sd_size = ndr_size_security_descriptor(sd_store->sd, NULL, 0)
- + sizeof(SEC_DESC_BUF);
-
- status = marshall_sec_desc_buf(ctx, sd_store, &data.dptr, &data.dsize);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("sec_desc_upg_fn: Failed to parse new sec_desc for %s\n", key.dptr ));
- return 0;
- }
-
- result = tdb_store( tdb_printers, key, data, TDB_REPLACE );
-
- /* 0 to continue and non-zero to stop traversal */
-
- return (result == -1);
-}
-
-/*******************************************************************
-*******************************************************************/
-
-static bool upgrade_to_version_4(void)
-{
- TALLOC_CTX *ctx;
- int result;
-
- DEBUG(0,("upgrade_to_version_4: upgrading printer security descriptors\n"));
-
- if ( !(ctx = talloc_init( "upgrade_to_version_4" )) )
- return False;
-
- result = tdb_traverse( tdb_printers, sec_desc_upg_fn, ctx );
-
- talloc_destroy( ctx );
-
- return ( result != -1 );
-}
-
-/*******************************************************************
- Fix an issue with security descriptors. Printer sec_desc must
- use more than the generic bits that were previously used
- in <= 3.0.14a. They must also have a owner and group SID assigned.
- Otherwise, any printers than have been migrated to a Windows
- host using printmig.exe will not be accessible.
-*******************************************************************/
-
-static int normalize_printers_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
- TDB_DATA data, void *state )
-{
- TALLOC_CTX *ctx = talloc_tos();
- TDB_DATA new_key;
-
- if (!data.dptr || data.dsize == 0)
- return 0;
-
- /* upgrade printer records and security descriptors */
-
- if ( strncmp((const char *) key.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX) ) == 0 ) {
- new_key = make_printer_tdbkey(ctx, (const char *)key.dptr+strlen(PRINTERS_PREFIX) );
- }
- else if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) == 0 ) {
- new_key = make_printers_secdesc_tdbkey(ctx, (const char *)key.dptr+strlen(SECDESC_PREFIX) );
- }
- else {
- /* ignore this record */
- return 0;
- }
-
- /* delete the original record and store under the normalized key */
-
- if ( tdb_delete( the_tdb, key ) != 0 ) {
- DEBUG(0,("normalize_printers_fn: tdb_delete for [%s] failed!\n",
- key.dptr));
- return 1;
- }
-
- if ( tdb_store( the_tdb, new_key, data, TDB_REPLACE) != 0 ) {
- DEBUG(0,("normalize_printers_fn: failed to store new record for [%s]!\n",
- key.dptr));
- return 1;
- }
-
- return 0;
-}
-
-/*******************************************************************
-*******************************************************************/
-
-static bool upgrade_to_version_5(void)
-{
- TALLOC_CTX *ctx;
- int result;
-
- DEBUG(0,("upgrade_to_version_5: normalizing printer keys\n"));
-
- if ( !(ctx = talloc_init( "upgrade_to_version_5" )) )
- return False;
-
- result = tdb_traverse( tdb_printers, normalize_printers_fn, NULL );
-
- talloc_destroy( ctx );
-
- return ( result != -1 );
-}
-
-/****************************************************************************
- Open the NT printing tdbs. Done once before fork().
-****************************************************************************/
-
-bool nt_printing_init(struct messaging_context *msg_ctx)
-{
- const char *vstring = "INFO/version";
- WERROR win_rc;
- int32 vers_id;
-
- if ( tdb_drivers && tdb_printers && tdb_forms )
- return True;
-
- if (tdb_drivers)
- tdb_close(tdb_drivers);
- tdb_drivers = tdb_open_log(state_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
- if (!tdb_drivers) {
- DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
- state_path("ntdrivers.tdb"), strerror(errno) ));
- return False;
- }
-
- if (tdb_printers)
- tdb_close(tdb_printers);
- tdb_printers = tdb_open_log(state_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
- if (!tdb_printers) {
- DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
- state_path("ntprinters.tdb"), strerror(errno) ));
- return False;
- }
-
- if (tdb_forms)
- tdb_close(tdb_forms);
- tdb_forms = tdb_open_log(state_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
- if (!tdb_forms) {
- DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
- state_path("ntforms.tdb"), strerror(errno) ));
- return False;
- }
-
- /* handle a Samba upgrade */
-
- vers_id = tdb_fetch_int32(tdb_drivers, vstring);
- if (vers_id == -1) {
- DEBUG(10, ("Fresh database\n"));
- tdb_store_int32( tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5 );
- vers_id = NTDRIVERS_DATABASE_VERSION_5;
- }
-
- if ( vers_id != NTDRIVERS_DATABASE_VERSION_5 ) {
-
- if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) {
- if (!upgrade_to_version_3())
- return False;
- tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3);
- vers_id = NTDRIVERS_DATABASE_VERSION_3;
- }
-
- if ((vers_id == NTDRIVERS_DATABASE_VERSION_2) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_2)) {
- /* Written on a bigendian machine with old fetch_int code. Save as le. */
- /* The only upgrade between V2 and V3 is to save the version in little-endian. */
- tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3);
- vers_id = NTDRIVERS_DATABASE_VERSION_3;
- }
-
- if (vers_id == NTDRIVERS_DATABASE_VERSION_3 ) {
- if ( !upgrade_to_version_4() )
- return False;
- tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_4);
- vers_id = NTDRIVERS_DATABASE_VERSION_4;
- }
-
- if (vers_id == NTDRIVERS_DATABASE_VERSION_4 ) {
- if ( !upgrade_to_version_5() )
- return False;
- tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_5);
- vers_id = NTDRIVERS_DATABASE_VERSION_5;
- }
-
-
- if ( vers_id != NTDRIVERS_DATABASE_VERSION_5 ) {
- DEBUG(0,("nt_printing_init: Unknown printer database version [%d]\n", vers_id));
- return False;
- }
- }
-
- update_c_setprinter(True);
-
- /*
- * register callback to handle updating printers as new
- * drivers are installed
- */
-
- messaging_register(msg_ctx, NULL, MSG_PRINTER_DRVUPGRADE,
- do_drv_upgrade_printer);
-
- /*
- * register callback to handle updating printer data
- * when a driver is initialized
- */
-
- messaging_register(msg_ctx, NULL, MSG_PRINTERDATA_INIT_RESET,
- reset_all_printerdata);
-
- /* of course, none of the message callbacks matter if you don't
- tell messages.c that you interested in receiving PRINT_GENERAL
- msgs. This is done in serverid_register() */
-
-
- if ( lp_security() == SEC_ADS ) {
- win_rc = check_published_printers();
- if (!W_ERROR_IS_OK(win_rc))
- DEBUG(0, ("nt_printing_init: error checking published printers: %s\n", win_errstr(win_rc)));
- }
-
- return True;
-}
-
-/*******************************************************************
- Function to allow filename parsing "the old way".
-********************************************************************/
-
-static NTSTATUS driver_unix_convert(connection_struct *conn,
- const char *old_name,
- struct smb_filename **smb_fname)
-{
- NTSTATUS status;
- TALLOC_CTX *ctx = talloc_tos();
- char *name = talloc_strdup(ctx, old_name);
-
- if (!name) {
- return NT_STATUS_NO_MEMORY;
- }
- unix_format(name);
- name = unix_clean_name(ctx, name);
- if (!name) {
- return NT_STATUS_NO_MEMORY;
- }
- trim_string(name,"/","/");
-
- status = unix_convert(ctx, conn, name, smb_fname, 0);
- if (!NT_STATUS_IS_OK(status)) {
- return NT_STATUS_NO_MEMORY;
- }
-
- return NT_STATUS_OK;
-}
-
-/*******************************************************************
- tdb traversal function for counting printers.
-********************************************************************/
-
-static int traverse_counting_printers(TDB_CONTEXT *t, TDB_DATA key,
- TDB_DATA data, void *context)
-{
- int *printer_count = (int*)context;
-
- if (memcmp(PRINTERS_PREFIX, key.dptr, sizeof(PRINTERS_PREFIX)-1) == 0) {
- (*printer_count)++;
- DEBUG(10,("traverse_counting_printers: printer = [%s] printer_count = %d\n", key.dptr, *printer_count));
- }
-
- return 0;
-}
-
-/*******************************************************************
- Update the spooler global c_setprinter. This variable is initialized
- when the parent smbd starts with the number of existing printers. It
- is monotonically increased by the current number of printers *after*
- each add or delete printer RPC. Only Microsoft knows why... JRR020119
-********************************************************************/
-
-uint32 update_c_setprinter(bool initialize)
-{
- int32 c_setprinter;
- int32 printer_count = 0;
-
- tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
-
- /* Traverse the tdb, counting the printers */
- tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);
-
- /* If initializing, set c_setprinter to current printers count
- * otherwise, bump it by the current printer count
- */
- if (!initialize)
- c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER) + printer_count;
- else
- c_setprinter = printer_count;
-
- DEBUG(10,("update_c_setprinter: c_setprinter = %u\n", (unsigned int)c_setprinter));
- tdb_store_int32(tdb_printers, GLOBAL_C_SETPRINTER, c_setprinter);
-
- tdb_unlock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
-
- return (uint32)c_setprinter;
-}
-
-/*******************************************************************
- Get the spooler global c_setprinter, accounting for initialization.
-********************************************************************/
-
-uint32 get_c_setprinter(void)
-{
- int32 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER);
-
- if (c_setprinter == (int32)-1)
- c_setprinter = update_c_setprinter(True);
-
- DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter));
-
- return (uint32)c_setprinter;
-}
-
-/****************************************************************************
- Get builtin form struct list.
-****************************************************************************/
-
-int get_builtin_ntforms(nt_forms_struct **list)
-{
- *list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
- if (!*list) {
- return 0;
- }
- return ARRAY_SIZE(default_forms);
-}
-
-/****************************************************************************
- get a builtin form struct
-****************************************************************************/
-
-bool get_a_builtin_ntform_by_string(const char *form_name, nt_forms_struct *form)
-{
- int i;
- DEBUGADD(6,("Looking for builtin form %s \n", form_name));
- for (i=0; i<ARRAY_SIZE(default_forms); i++) {
- if (strequal(form_name,default_forms[i].name)) {
- DEBUGADD(6,("Found builtin form %s \n", form_name));
- memcpy(form,&default_forms[i],sizeof(*form));
- return true;
- }
- }
-
- return false;
-}
-
-/****************************************************************************
- get a form struct list.
-****************************************************************************/
-
-int get_ntforms(nt_forms_struct **list)
-{
- TDB_DATA kbuf, newkey, dbuf;
- nt_forms_struct form;
- int ret;
- int i;
- int n = 0;
-
- *list = NULL;
-
- for (kbuf = tdb_firstkey(tdb_forms);
- kbuf.dptr;
- newkey = tdb_nextkey(tdb_forms, kbuf), free(kbuf.dptr), kbuf=newkey)
- {
- if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0)
- continue;
-
- dbuf = tdb_fetch(tdb_forms, kbuf);
- if (!dbuf.dptr)
- continue;
-
- fstrcpy(form.name, (const char *)kbuf.dptr+strlen(FORMS_PREFIX));
- ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
- &i, &form.flag, &form.width, &form.length, &form.left,
- &form.top, &form.right, &form.bottom);
- SAFE_FREE(dbuf.dptr);
- if (ret != dbuf.dsize)
- continue;
-
- *list = SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1);
- if (!*list) {
- DEBUG(0,("get_ntforms: Realloc fail.\n"));
- return 0;
- }
- (*list)[n] = form;
- n++;
- }
-
-
- return n;
-}
-
-/****************************************************************************
-write a form struct list
-****************************************************************************/
-
-int write_ntforms(nt_forms_struct **list, int number)
-{
- TALLOC_CTX *ctx = talloc_tos();
- char *buf = NULL;
- char *key = NULL;
- int len;
- TDB_DATA dbuf;
- int i;
-
- for (i=0;i<number;i++) {
- /* save index, so list is rebuilt in correct order */
- len = tdb_pack(NULL, 0, "dddddddd",
- i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
- (*list)[i].left, (*list)[i].top, (*list)[i].right,
- (*list)[i].bottom);
- if (!len) {
- continue;
- }
- buf = TALLOC_ARRAY(ctx, char, len);
- if (!buf) {
- return 0;
- }
- len = tdb_pack((uint8 *)buf, len, "dddddddd",
- i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
- (*list)[i].left, (*list)[i].top, (*list)[i].right,
- (*list)[i].bottom);
- key = talloc_asprintf(ctx, "%s%s", FORMS_PREFIX, (*list)[i].name);
- if (!key) {
- return 0;
- }
- dbuf.dsize = len;
- dbuf.dptr = (uint8 *)buf;
- if (tdb_store_bystring(tdb_forms, key, dbuf, TDB_REPLACE) != 0) {
- TALLOC_FREE(key);
- TALLOC_FREE(buf);
- break;
- }
- TALLOC_FREE(key);
- TALLOC_FREE(buf);
- }
-
- return i;
-}
-
-/****************************************************************************
-add a form struct at the end of the list
-****************************************************************************/
-bool add_a_form(nt_forms_struct **list, struct spoolss_AddFormInfo1 *form, int *count)
-{
- int n=0;
- bool update;
-
- /*
- * NT tries to add forms even when
- * they are already in the base
- * only update the values if already present
- */
-
- update=False;
-
- for (n=0; n<*count; n++) {
- if ( strequal((*list)[n].name, form->form_name) ) {
- update=True;
- break;
- }
- }
-
- if (update==False) {
- if((*list=SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1)) == NULL) {
- DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
- return False;
- }
- fstrcpy((*list)[n].name, form->form_name);
- (*count)++;
- }
-
- (*list)[n].flag = form->flags;
- (*list)[n].width = form->size.width;
- (*list)[n].length = form->size.height;
- (*list)[n].left = form->area.left;
- (*list)[n].top = form->area.top;
- (*list)[n].right = form->area.right;
- (*list)[n].bottom = form->area.bottom;
-
- DEBUG(6,("add_a_form: Successfully %s form [%s]\n",
- update ? "updated" : "added", form->form_name));
-
- return True;
-}
-
-/****************************************************************************
- Delete a named form struct.
-****************************************************************************/
-
-bool delete_a_form(nt_forms_struct **list, const char *del_name, int *count, WERROR *ret)
-{
- char *key = NULL;
- int n=0;
-
- *ret = WERR_OK;
-
- for (n=0; n<*count; n++) {
- if (!strncmp((*list)[n].name, del_name, strlen(del_name))) {
- DEBUG(103, ("delete_a_form, [%s] in list\n", del_name));
- break;
- }
- }
-
- if (n == *count) {
- DEBUG(10,("delete_a_form, [%s] not found\n", del_name));
- *ret = WERR_INVALID_FORM_NAME;
- return False;
- }
-
- if (asprintf(&key, "%s%s", FORMS_PREFIX, (*list)[n].name) < 0) {
- *ret = WERR_NOMEM;
- return false;
- }
- if (tdb_delete_bystring(tdb_forms, key) != 0) {
- SAFE_FREE(key);
- *ret = WERR_NOMEM;
- return False;
- }
- SAFE_FREE(key);
- return true;
-}
-
-/****************************************************************************
- Update a form struct.
-****************************************************************************/
-
-void update_a_form(nt_forms_struct **list, struct spoolss_AddFormInfo1 *form, int count)
-{
- int n=0;
-
- DEBUG(106, ("[%s]\n", form->form_name));
- for (n=0; n<count; n++) {
- DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
- if (!strncmp((*list)[n].name, form->form_name, strlen(form->form_name)))
- break;
- }
-
- if (n==count) return;
-
- (*list)[n].flag = form->flags;
- (*list)[n].width = form->size.width;
- (*list)[n].length = form->size.height;
- (*list)[n].left = form->area.left;
- (*list)[n].top = form->area.top;
- (*list)[n].right = form->area.right;
- (*list)[n].bottom = form->area.bottom;
-}
-
-/****************************************************************************
- Get the nt drivers list.
- Traverse the database and look-up the matching names.
-****************************************************************************/
-int get_ntdrivers(fstring **list, const char *architecture, uint32 version)
-{
- int total=0;
- const char *short_archi;
- char *key = NULL;
- TDB_DATA kbuf, newkey;
-
- short_archi = get_short_archi(architecture);
- if (!short_archi) {
- return 0;
- }
-
- if (asprintf(&key, "%s%s/%d/", DRIVERS_PREFIX,
- short_archi, version) < 0) {
- return 0;
- }
-
- for (kbuf = tdb_firstkey(tdb_drivers);
- kbuf.dptr;
- newkey = tdb_nextkey(tdb_drivers, kbuf), free(kbuf.dptr), kbuf=newkey) {
-
- if (strncmp((const char *)kbuf.dptr, key, strlen(key)) != 0)
- continue;
-
- if((*list = SMB_REALLOC_ARRAY(*list, fstring, total+1)) == NULL) {
- DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
- SAFE_FREE(key);
- return -1;
- }
-
- fstrcpy((*list)[total], (const char *)kbuf.dptr+strlen(key));
- total++;
- }
-
- SAFE_FREE(key);
- return(total);
-}
-
-/****************************************************************************
- Function to do the mapping between the long architecture name and
- the short one.
-****************************************************************************/
-
-const char *get_short_archi(const char *long_archi)
-{
- int i=-1;
-
- DEBUG(107,("Getting architecture dependant directory\n"));
- do {
- i++;
- } while ( (archi_table[i].long_archi!=NULL ) &&
- StrCaseCmp(long_archi, archi_table[i].long_archi) );
-
- if (archi_table[i].long_archi==NULL) {
- DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
- return NULL;
- }
-
- /* this might be client code - but shouldn't this be an fstrcpy etc? */
-
- DEBUGADD(108,("index: [%d]\n", i));
- DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
- DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
-
- return archi_table[i].short_archi;
-}
-
-/****************************************************************************
- Version information in Microsoft files is held in a VS_VERSION_INFO structure.
- There are two case to be covered here: PE (Portable Executable) and NE (New
- Executable) files. Both files support the same INFO structure, but PE files
- store the signature in unicode, and NE files store it as !unicode.
- returns -1 on error, 1 on version info found, and 0 on no version info found.
-****************************************************************************/
-
-static int get_file_version(files_struct *fsp, char *fname,uint32 *major, uint32 *minor)
-{
- int i;
- char *buf = NULL;
- ssize_t byte_count;
-
- if ((buf=(char *)SMB_MALLOC(DOS_HEADER_SIZE)) == NULL) {
- DEBUG(0,("get_file_version: PE file [%s] DOS Header malloc failed bytes = %d\n",
- fname, DOS_HEADER_SIZE));
- goto error_exit;
- }
-
- if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
- DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %lu\n",
- fname, (unsigned long)byte_count));
- goto no_version_info;
- }
-
- /* Is this really a DOS header? */
- if (SVAL(buf,DOS_HEADER_MAGIC_OFFSET) != DOS_HEADER_MAGIC) {
- DEBUG(6,("get_file_version: File [%s] bad DOS magic = 0x%x\n",
- fname, SVAL(buf,DOS_HEADER_MAGIC_OFFSET)));
- goto no_version_info;
- }
-
- /* Skip OEM header (if any) and the DOS stub to start of Windows header */
- if (SMB_VFS_LSEEK(fsp, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
- DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
- fname, errno));
- /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
- goto no_version_info;
- }
-
- /* Note: DOS_HEADER_SIZE and NE_HEADER_SIZE are incidentally same */
- if ((byte_count = vfs_read_data(fsp, buf, NE_HEADER_SIZE)) < NE_HEADER_SIZE) {
- DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %lu\n",
- fname, (unsigned long)byte_count));
- /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
- goto no_version_info;
- }
-
- /* The header may be a PE (Portable Executable) or an NE (New Executable) */
- if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
- unsigned int num_sections;
- unsigned int section_table_bytes;
-
- /* Just skip over optional header to get to section table */
- if (SMB_VFS_LSEEK(fsp,
- SVAL(buf,PE_HEADER_OPTIONAL_HEADER_SIZE)-(NE_HEADER_SIZE-PE_HEADER_SIZE),
- SEEK_CUR) == (SMB_OFF_T)-1) {
- DEBUG(3,("get_file_version: File [%s] Windows optional header too short, errno = %d\n",
- fname, errno));
- goto error_exit;
- }
-
- /* get the section table */
- num_sections = SVAL(buf,PE_HEADER_NUMBER_OF_SECTIONS);
- section_table_bytes = num_sections * PE_HEADER_SECT_HEADER_SIZE;
- if (section_table_bytes == 0)
- goto error_exit;
-
- SAFE_FREE(buf);
- if ((buf=(char *)SMB_MALLOC(section_table_bytes)) == NULL) {
- DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
- fname, section_table_bytes));
- goto error_exit;
- }
-
- if ((byte_count = vfs_read_data(fsp, buf, section_table_bytes)) < section_table_bytes) {
- DEBUG(3,("get_file_version: PE file [%s] Section header too short, bytes read = %lu\n",
- fname, (unsigned long)byte_count));
- goto error_exit;
- }
-
- /* Iterate the section table looking for the resource section ".rsrc" */
- for (i = 0; i < num_sections; i++) {
- int sec_offset = i * PE_HEADER_SECT_HEADER_SIZE;
-
- if (strcmp(".rsrc", &buf[sec_offset+PE_HEADER_SECT_NAME_OFFSET]) == 0) {
- unsigned int section_pos = IVAL(buf,sec_offset+PE_HEADER_SECT_PTR_DATA_OFFSET);
- unsigned int section_bytes = IVAL(buf,sec_offset+PE_HEADER_SECT_SIZE_DATA_OFFSET);
-
- if (section_bytes == 0)
- goto error_exit;
-
- SAFE_FREE(buf);
- if ((buf=(char *)SMB_MALLOC(section_bytes)) == NULL) {
- DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
- fname, section_bytes));
- goto error_exit;
- }
-
- /* Seek to the start of the .rsrc section info */
- if (SMB_VFS_LSEEK(fsp, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
- DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
- fname, errno));
- goto error_exit;
- }
-
- if ((byte_count = vfs_read_data(fsp, buf, section_bytes)) < section_bytes) {
- DEBUG(3,("get_file_version: PE file [%s] .rsrc section too short, bytes read = %lu\n",
- fname, (unsigned long)byte_count));
- goto error_exit;
- }
-
- if (section_bytes < VS_VERSION_INFO_UNICODE_SIZE)
- goto error_exit;
-
- for (i=0; i<section_bytes-VS_VERSION_INFO_UNICODE_SIZE; i++) {
- /* Scan for 1st 3 unicoded bytes followed by word aligned magic value */
- if (buf[i] == 'V' && buf[i+1] == '\0' && buf[i+2] == 'S') {
- /* Align to next long address */
- int pos = (i + sizeof(VS_SIGNATURE)*2 + 3) & 0xfffffffc;
-
- if (IVAL(buf,pos) == VS_MAGIC_VALUE) {
- *major = IVAL(buf,pos+VS_MAJOR_OFFSET);
- *minor = IVAL(buf,pos+VS_MINOR_OFFSET);
-
- DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
- fname, *major, *minor,
- (*major>>16)&0xffff, *major&0xffff,
- (*minor>>16)&0xffff, *minor&0xffff));
- SAFE_FREE(buf);
- return 1;
- }
- }
- }
- }
- }
-
- /* Version info not found, fall back to origin date/time */
- DEBUG(10,("get_file_version: PE file [%s] has no version info\n", fname));
- SAFE_FREE(buf);
- return 0;
-
- } else if (SVAL(buf,NE_HEADER_SIGNATURE_OFFSET) == NE_HEADER_SIGNATURE) {
- if (CVAL(buf,NE_HEADER_TARGET_OS_OFFSET) != NE_HEADER_TARGOS_WIN ) {
- DEBUG(3,("get_file_version: NE file [%s] wrong target OS = 0x%x\n",
- fname, CVAL(buf,NE_HEADER_TARGET_OS_OFFSET)));
- /* At this point, we assume the file is in error. It still could be somthing
- * else besides a NE file, but it unlikely at this point. */
- goto error_exit;
- }
-
- /* Allocate a bit more space to speed up things */
- SAFE_FREE(buf);
- if ((buf=(char *)SMB_MALLOC(VS_NE_BUF_SIZE)) == NULL) {
- DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes = %d\n",
- fname, PE_HEADER_SIZE));
- goto error_exit;
- }
-
- /* This is a HACK! I got tired of trying to sort through the messy
- * 'NE' file format. If anyone wants to clean this up please have at
- * it, but this works. 'NE' files will eventually fade away. JRR */
- while((byte_count = vfs_read_data(fsp, buf, VS_NE_BUF_SIZE)) > 0) {
- /* Cover case that should not occur in a well formed 'NE' .dll file */
- if (byte_count-VS_VERSION_INFO_SIZE <= 0) break;
-
- for(i=0; i<byte_count; i++) {
- /* Fast skip past data that can't possibly match */
- if (buf[i] != 'V') continue;
-
- /* Potential match data crosses buf boundry, move it to beginning
- * of buf, and fill the buf with as much as it will hold. */
- if (i>byte_count-VS_VERSION_INFO_SIZE) {
- int bc;
-
- memcpy(buf, &buf[i], byte_count-i);
- if ((bc = vfs_read_data(fsp, &buf[byte_count-i], VS_NE_BUF_SIZE-
- (byte_count-i))) < 0) {
-
- DEBUG(0,("get_file_version: NE file [%s] Read error, errno=%d\n",
- fname, errno));
- goto error_exit;
- }
-
- byte_count = bc + (byte_count - i);
- if (byte_count<VS_VERSION_INFO_SIZE) break;
-
- i = 0;
- }
-
- /* Check that the full signature string and the magic number that
- * follows exist (not a perfect solution, but the chances that this
- * occurs in code is, well, remote. Yes I know I'm comparing the 'V'
- * twice, as it is simpler to read the code. */
- if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
- /* Compute skip alignment to next long address */
- int skip = -(SMB_VFS_LSEEK(fsp, 0, SEEK_CUR) - (byte_count - i) +
- sizeof(VS_SIGNATURE)) & 3;
- if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
-
- *major = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MAJOR_OFFSET);
- *minor = IVAL(buf,i+sizeof(VS_SIGNATURE)+skip+VS_MINOR_OFFSET);
- DEBUG(6,("get_file_version: NE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
- fname, *major, *minor,
- (*major>>16)&0xffff, *major&0xffff,
- (*minor>>16)&0xffff, *minor&0xffff));
- SAFE_FREE(buf);
- return 1;
- }
- }
- }
-
- /* Version info not found, fall back to origin date/time */
- DEBUG(0,("get_file_version: NE file [%s] Version info not found\n", fname));
- SAFE_FREE(buf);
- return 0;
-
- } else
- /* Assume this isn't an error... the file just looks sort of like a PE/NE file */
- DEBUG(3,("get_file_version: File [%s] unknown file format, signature = 0x%x\n",
- fname, IVAL(buf,PE_HEADER_SIGNATURE_OFFSET)));
-
- no_version_info:
- SAFE_FREE(buf);
- return 0;
-
- error_exit:
- SAFE_FREE(buf);
- return -1;
-}
-
-/****************************************************************************
-Drivers for Microsoft systems contain multiple files. Often, multiple drivers
-share one or more files. During the MS installation process files are checked
-to insure that only a newer version of a shared file is installed over an
-older version. There are several possibilities for this comparison. If there
-is no previous version, the new one is newer (obviously). If either file is
-missing the version info structure, compare the creation date (on Unix use
-the modification date). Otherwise chose the numerically larger version number.
-****************************************************************************/
-
-static int file_version_is_newer(connection_struct *conn, fstring new_file, fstring old_file)
-{
- bool use_version = true;
-
- uint32 new_major;
- uint32 new_minor;
- time_t new_create_time;
-
- uint32 old_major;
- uint32 old_minor;
- time_t old_create_time;
-
- struct smb_filename *smb_fname = NULL;
- files_struct *fsp = NULL;
- SMB_STRUCT_STAT st;
-
- NTSTATUS status;
- int ret;
-
- SET_STAT_INVALID(st);
- new_create_time = (time_t)0;
- old_create_time = (time_t)0;
-
- /* Get file version info (if available) for previous file (if it exists) */
- status = driver_unix_convert(conn, old_file, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto error_exit;
- }
-
- status = SMB_VFS_CREATE_FILE(
- conn, /* conn */
- NULL, /* req */
- 0, /* root_dir_fid */
- smb_fname, /* fname */
- FILE_GENERIC_READ, /* access_mask */
- FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */
- FILE_OPEN, /* create_disposition*/
- 0, /* create_options */
- FILE_ATTRIBUTE_NORMAL, /* file_attributes */
- INTERNAL_OPEN_ONLY, /* oplock_request */
- 0, /* allocation_size */
- 0, /* private_flags */
- NULL, /* sd */
- NULL, /* ea_list */
- &fsp, /* result */
- NULL); /* pinfo */
-
- if (!NT_STATUS_IS_OK(status)) {
- /* Old file not found, so by definition new file is in fact newer */
- DEBUG(10,("file_version_is_newer: Can't open old file [%s], "
- "errno = %d\n", smb_fname_str_dbg(smb_fname),
- errno));
- ret = 1;
- goto done;
-
- } else {
- ret = get_file_version(fsp, old_file, &old_major, &old_minor);
- if (ret == -1) {
- goto error_exit;
- }
-
- if (!ret) {
- DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
- old_file));
- use_version = false;
- if (SMB_VFS_FSTAT(fsp, &st) == -1) {
- goto error_exit;
- }
- old_create_time = convert_timespec_to_time_t(st.st_ex_mtime);
- DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n",
- (long)old_create_time));
- }
- }
- close_file(NULL, fsp, NORMAL_CLOSE);
- fsp = NULL;
-
- /* Get file version info (if available) for new file */
- status = driver_unix_convert(conn, new_file, &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- goto error_exit;
- }
-
- status = SMB_VFS_CREATE_FILE(
- conn, /* conn */
- NULL, /* req */
- 0, /* root_dir_fid */
- smb_fname, /* fname */
- FILE_GENERIC_READ, /* access_mask */
- FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */
- FILE_OPEN, /* create_disposition*/
- 0, /* create_options */
- FILE_ATTRIBUTE_NORMAL, /* file_attributes */
- INTERNAL_OPEN_ONLY, /* oplock_request */
- 0, /* allocation_size */
- 0, /* private_flags */
- NULL, /* sd */
- NULL, /* ea_list */
- &fsp, /* result */
- NULL); /* pinfo */
-
- if (!NT_STATUS_IS_OK(status)) {
- /* New file not found, this shouldn't occur if the caller did its job */
- DEBUG(3,("file_version_is_newer: Can't open new file [%s], "
- "errno = %d\n", smb_fname_str_dbg(smb_fname), errno));
- goto error_exit;
-
- } else {
- ret = get_file_version(fsp, new_file, &new_major, &new_minor);
- if (ret == -1) {
- goto error_exit;
- }
-
- if (!ret) {
- DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
- new_file));
- use_version = false;
- if (SMB_VFS_FSTAT(fsp, &st) == -1) {
- goto error_exit;
- }
- new_create_time = convert_timespec_to_time_t(st.st_ex_mtime);
- DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n",
- (long)new_create_time));
- }
- }
- close_file(NULL, fsp, NORMAL_CLOSE);
- fsp = NULL;
-
- if (use_version && (new_major != old_major || new_minor != old_minor)) {
- /* Compare versions and choose the larger version number */
- if (new_major > old_major ||
- (new_major == old_major && new_minor > old_minor)) {
-
- DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
- ret = 1;
- goto done;
- }
- else {
- DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
- ret = 0;
- goto done;
- }
-
- } else {
- /* Compare modification time/dates and choose the newest time/date */
- if (new_create_time > old_create_time) {
- DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
- ret = 1;
- goto done;
- }
- else {
- DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
- ret = 0;
- goto done;
- }
- }
-
- error_exit:
- if(fsp)
- close_file(NULL, fsp, NORMAL_CLOSE);
- ret = -1;
- done:
- TALLOC_FREE(smb_fname);
- return ret;
-}
-
-/****************************************************************************
-Determine the correct cVersion associated with an architecture and driver
-****************************************************************************/
-static uint32 get_correct_cversion(struct pipes_struct *p,
- const char *architecture,
- const char *driverpath_in,
- WERROR *perr)
-{
- int cversion;
- NTSTATUS nt_status;
- struct smb_filename *smb_fname = NULL;
- char *driverpath = NULL;
- files_struct *fsp = NULL;
- connection_struct *conn = NULL;
- NTSTATUS status;
- char *oldcwd;
- fstring printdollar;
- int printdollar_snum;
-
- *perr = WERR_INVALID_PARAM;
-
- /* If architecture is Windows 95/98/ME, the version is always 0. */
- if (strcmp(architecture, SPL_ARCH_WIN40) == 0) {
- DEBUG(10,("get_correct_cversion: Driver is Win9x, cversion = 0\n"));
- *perr = WERR_OK;
- return 0;
- }
-
- /* If architecture is Windows x64, the version is always 3. */
- if (strcmp(architecture, SPL_ARCH_X64) == 0) {
- DEBUG(10,("get_correct_cversion: Driver is x64, cversion = 3\n"));
- *perr = WERR_OK;
- return 3;
- }
-
- fstrcpy(printdollar, "print$");
-
- printdollar_snum = find_service(printdollar);
- if (printdollar_snum == -1) {
- *perr = WERR_NO_SUCH_SHARE;
- return -1;
- }
-
- nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
- lp_pathname(printdollar_snum),
- p->server_info, &oldcwd);
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0,("get_correct_cversion: create_conn_struct "
- "returned %s\n", nt_errstr(nt_status)));
- *perr = ntstatus_to_werror(nt_status);
- return -1;
- }
-
- /* Open the driver file (Portable Executable format) and determine the
- * deriver the cversion. */
- driverpath = talloc_asprintf(talloc_tos(),
- "%s/%s",
- architecture,
- driverpath_in);
- if (!driverpath) {
- *perr = WERR_NOMEM;
- goto error_exit;
- }
-
- nt_status = driver_unix_convert(conn, driverpath, &smb_fname);
- if (!NT_STATUS_IS_OK(nt_status)) {
- *perr = ntstatus_to_werror(nt_status);
- goto error_exit;
- }
-
- nt_status = vfs_file_exist(conn, smb_fname);
- if (!NT_STATUS_IS_OK(nt_status)) {
- *perr = WERR_BADFILE;
- goto error_exit;
- }
-
- status = SMB_VFS_CREATE_FILE(
- conn, /* conn */
- NULL, /* req */
- 0, /* root_dir_fid */
- smb_fname, /* fname */
- FILE_GENERIC_READ, /* access_mask */
- FILE_SHARE_READ | FILE_SHARE_WRITE, /* share_access */
- FILE_OPEN, /* create_disposition*/
- 0, /* create_options */
- FILE_ATTRIBUTE_NORMAL, /* file_attributes */
- INTERNAL_OPEN_ONLY, /* oplock_request */
- 0, /* private_flags */
- 0, /* allocation_size */
- NULL, /* sd */
- NULL, /* ea_list */
- &fsp, /* result */
- NULL); /* pinfo */
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = "
- "%d\n", smb_fname_str_dbg(smb_fname), errno));
- *perr = WERR_ACCESS_DENIED;
- goto error_exit;
- } else {
- uint32 major;
- uint32 minor;
- int ret;
-
- ret = get_file_version(fsp, smb_fname->base_name, &major, &minor);
- if (ret == -1) goto error_exit;
-
- if (!ret) {
- DEBUG(6,("get_correct_cversion: Version info not "
- "found [%s]\n",
- smb_fname_str_dbg(smb_fname)));
- goto error_exit;
- }
-
- /*
- * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
- * for more details. Version in this case is not just the version of the
- * file, but the version in the sense of kernal mode (2) vs. user mode
- * (3) drivers. Other bits of the version fields are the version info.
- * JRR 010716
- */
- cversion = major & 0x0000ffff;
- switch (cversion) {
- case 2: /* WinNT drivers */
- case 3: /* Win2K drivers */
- break;
-
- default:
- DEBUG(6,("get_correct_cversion: cversion "
- "invalid [%s] cversion = %d\n",
- smb_fname_str_dbg(smb_fname),
- cversion));
- goto error_exit;
- }
-
- DEBUG(10,("get_correct_cversion: Version info found [%s] major"
- " = 0x%x minor = 0x%x\n",
- smb_fname_str_dbg(smb_fname), major, minor));
- }
-
- DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
- smb_fname_str_dbg(smb_fname), cversion));
-
- goto done;
-
- error_exit:
- cversion = -1;
- done:
- TALLOC_FREE(smb_fname);
- if (fsp != NULL) {
- close_file(NULL, fsp, NORMAL_CLOSE);
- }
- if (conn != NULL) {
- vfs_ChDir(conn, oldcwd);
- conn_free(conn);
- }
- if (cversion != -1) {
- *perr = WERR_OK;
- }
- return cversion;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-#define strip_driver_path(_mem_ctx, _element) do { \
- if ((_p = strrchr((_element), '\\')) != NULL) { \
- (_element) = talloc_asprintf((_mem_ctx), "%s", _p+1); \
- W_ERROR_HAVE_NO_MEMORY((_element)); \
- } \
-} while (0);
-
-static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
- struct pipes_struct *rpc_pipe,
- const char *architecture,
- const char **driver_path,
- const char **data_file,
- const char **config_file,
- const char **help_file,
- struct spoolss_StringArray *dependent_files,
- uint32_t *version)
-{
- const char *short_architecture;
- int i;
- WERROR err;
- char *_p;
-
- /* clean up the driver name.
- * we can get .\driver.dll
- * or worse c:\windows\system\driver.dll !
- */
- /* using an intermediate string to not have overlaping memcpy()'s */
-
- strip_driver_path(mem_ctx, *driver_path);
- strip_driver_path(mem_ctx, *data_file);
- strip_driver_path(mem_ctx, *config_file);
- strip_driver_path(mem_ctx, *help_file);
-
- if (dependent_files && dependent_files->string) {
- for (i=0; dependent_files->string[i]; i++) {
- strip_driver_path(mem_ctx, dependent_files->string[i]);
- }
- }
-
- short_architecture = get_short_archi(architecture);
- if (!short_architecture) {
- return WERR_UNKNOWN_PRINTER_DRIVER;
- }
-
- /* jfm:7/16/2000 the client always sends the cversion=0.
- * The server should check which version the driver is by reading
- * the PE header of driver->driverpath.
- *
- * For Windows 95/98 the version is 0 (so the value sent is correct)
- * For Windows NT (the architecture doesn't matter)
- * NT 3.1: cversion=0
- * NT 3.5/3.51: cversion=1
- * NT 4: cversion=2
- * NT2K: cversion=3
- */
-
- *version = get_correct_cversion(rpc_pipe, short_architecture,
- *driver_path, &err);
- if (*version == -1) {
- return err;
- }
-
- return WERR_OK;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-WERROR clean_up_driver_struct(struct pipes_struct *rpc_pipe,
- struct spoolss_AddDriverInfoCtr *r)
-{
- switch (r->level) {
- case 3:
- return clean_up_driver_struct_level(r, rpc_pipe,
- r->info.info3->architecture,
- &r->info.info3->driver_path,
- &r->info.info3->data_file,
- &r->info.info3->config_file,
- &r->info.info3->help_file,
- r->info.info3->dependent_files,
- &r->info.info3->version);
- case 6:
- return clean_up_driver_struct_level(r, rpc_pipe,
- r->info.info6->architecture,
- &r->info.info6->driver_path,
- &r->info.info6->data_file,
- &r->info.info6->config_file,
- &r->info.info6->help_file,
- r->info.info6->dependent_files,
- &r->info.info6->version);
- default:
- return WERR_NOT_SUPPORTED;
- }
-}
-
-/****************************************************************************
- This function sucks and should be replaced. JRA.
-****************************************************************************/
-
-static void convert_level_6_to_level3(struct spoolss_AddDriverInfo3 *dst,
- const struct spoolss_AddDriverInfo6 *src)
-{
- dst->version = src->version;
-
- dst->driver_name = src->driver_name;
- dst->architecture = src->architecture;
- dst->driver_path = src->driver_path;
- dst->data_file = src->data_file;
- dst->config_file = src->config_file;
- dst->help_file = src->help_file;
- dst->monitor_name = src->monitor_name;
- dst->default_datatype = src->default_datatype;
- dst->_ndr_size_dependent_files = src->_ndr_size_dependent_files;
- dst->dependent_files = src->dependent_files;
-}
-
-/****************************************************************************
- This function sucks and should be replaced. JRA.
-****************************************************************************/
-
-static void convert_level_8_to_level3(TALLOC_CTX *mem_ctx,
- struct spoolss_AddDriverInfo3 *dst,
- const struct spoolss_DriverInfo8 *src)
-{
- dst->version = src->version;
- dst->driver_name = src->driver_name;
- dst->architecture = src->architecture;
- dst->driver_path = src->driver_path;
- dst->data_file = src->data_file;
- dst->config_file = src->config_file;
- dst->help_file = src->help_file;
- dst->monitor_name = src->monitor_name;
- dst->default_datatype = src->default_datatype;
- if (src->dependent_files) {
- dst->dependent_files = talloc_zero(mem_ctx, struct spoolss_StringArray);
- if (!dst->dependent_files) return;
- dst->dependent_files->string = src->dependent_files;
- } else {
- dst->dependent_files = NULL;
- }
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR move_driver_file_to_download_area(TALLOC_CTX *mem_ctx,
- connection_struct *conn,
- const char *driver_file,
- const char *short_architecture,
- uint32_t driver_version,
- uint32_t version)
-{
- struct smb_filename *smb_fname_old = NULL;
- struct smb_filename *smb_fname_new = NULL;
- char *old_name = NULL;
- char *new_name = NULL;
- NTSTATUS status;
- WERROR ret;
-
- old_name = talloc_asprintf(mem_ctx, "%s/%s",
- short_architecture, driver_file);
- W_ERROR_HAVE_NO_MEMORY(old_name);
-
- new_name = talloc_asprintf(mem_ctx, "%s/%d/%s",
- short_architecture, driver_version, driver_file);
- if (new_name == NULL) {
- TALLOC_FREE(old_name);
- return WERR_NOMEM;
- }
-
- if (version != -1 && (version = file_version_is_newer(conn, old_name, new_name)) > 0) {
-
- status = driver_unix_convert(conn, old_name, &smb_fname_old);
- if (!NT_STATUS_IS_OK(status)) {
- ret = WERR_NOMEM;
- goto out;
- }
-
- /* Setup a synthetic smb_filename struct */
- smb_fname_new = TALLOC_ZERO_P(mem_ctx, struct smb_filename);
- if (!smb_fname_new) {
- ret = WERR_NOMEM;
- goto out;
- }
-
- smb_fname_new->base_name = new_name;
-
- DEBUG(10,("move_driver_file_to_download_area: copying '%s' to "
- "'%s'\n", smb_fname_old->base_name,
- smb_fname_new->base_name));
-
- status = copy_file(mem_ctx, conn, smb_fname_old, smb_fname_new,
- OPENX_FILE_EXISTS_TRUNCATE |
- OPENX_FILE_CREATE_IF_NOT_EXIST,
- 0, false);
-
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0,("move_driver_file_to_download_area: Unable "
- "to rename [%s] to [%s]: %s\n",
- smb_fname_old->base_name, new_name,
- nt_errstr(status)));
- ret = WERR_ACCESS_DENIED;
- goto out;
- }
- }
-
- ret = WERR_OK;
- out:
- TALLOC_FREE(smb_fname_old);
- TALLOC_FREE(smb_fname_new);
- return ret;
-}
-
-WERROR move_driver_to_download_area(struct pipes_struct *p,
- struct spoolss_AddDriverInfoCtr *r,
- WERROR *perr)
-{
- struct spoolss_AddDriverInfo3 *driver;
- struct spoolss_AddDriverInfo3 converted_driver;
- const char *short_architecture;
- struct smb_filename *smb_dname = NULL;
- char *new_dir = NULL;
- connection_struct *conn = NULL;
- NTSTATUS nt_status;
- int i;
- TALLOC_CTX *ctx = talloc_tos();
- int ver = 0;
- char *oldcwd;
- fstring printdollar;
- int printdollar_snum;
-
- *perr = WERR_OK;
-
- switch (r->level) {
- case 3:
- driver = r->info.info3;
- break;
- case 6:
- convert_level_6_to_level3(&converted_driver, r->info.info6);
- driver = &converted_driver;
- break;
- default:
- DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)r->level));
- return WERR_UNKNOWN_LEVEL;
- }
-
- short_architecture = get_short_archi(driver->architecture);
- if (!short_architecture) {
- return WERR_UNKNOWN_PRINTER_DRIVER;
- }
-
- fstrcpy(printdollar, "print$");
-
- printdollar_snum = find_service(printdollar);
- if (printdollar_snum == -1) {
- *perr = WERR_NO_SUCH_SHARE;
- return WERR_NO_SUCH_SHARE;
- }
-
- nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
- lp_pathname(printdollar_snum),
- p->server_info, &oldcwd);
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0,("move_driver_to_download_area: create_conn_struct "
- "returned %s\n", nt_errstr(nt_status)));
- *perr = ntstatus_to_werror(nt_status);
- return *perr;
- }
-
- new_dir = talloc_asprintf(ctx,
- "%s/%d",
- short_architecture,
- driver->version);
- if (!new_dir) {
- *perr = WERR_NOMEM;
- goto err_exit;
- }
- nt_status = driver_unix_convert(conn, new_dir, &smb_dname);
- if (!NT_STATUS_IS_OK(nt_status)) {
- *perr = WERR_NOMEM;
- goto err_exit;
- }
-
- DEBUG(5,("Creating first directory: %s\n", smb_dname->base_name));
-
- create_directory(conn, NULL, smb_dname);
-
- /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
- * listed for this driver which has already been moved, skip it (note:
- * drivers may list the same file name several times. Then check if the
- * file already exists in archi\version\, if so, check that the version
- * info (or time stamps if version info is unavailable) is newer (or the
- * date is later). If it is, move it to archi\version\filexxx.yyy.
- * Otherwise, delete the file.
- *
- * If a file is not moved to archi\version\ because of an error, all the
- * rest of the 'unmoved' driver files are removed from archi\. If one or
- * more of the driver's files was already moved to archi\version\, it
- * potentially leaves the driver in a partially updated state. Version
- * trauma will most likely occur if an client attempts to use any printer
- * bound to the driver. Perhaps a rewrite to make sure the moves can be
- * done is appropriate... later JRR
- */
-
- DEBUG(5,("Moving files now !\n"));
-
- if (driver->driver_path && strlen(driver->driver_path)) {
-
- *perr = move_driver_file_to_download_area(ctx,
- conn,
- driver->driver_path,
- short_architecture,
- driver->version,
- ver);
- if (!W_ERROR_IS_OK(*perr)) {
- if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
- ver = -1;
- }
- goto err_exit;
- }
- }
-
- if (driver->data_file && strlen(driver->data_file)) {
- if (!strequal(driver->data_file, driver->driver_path)) {
-
- *perr = move_driver_file_to_download_area(ctx,
- conn,
- driver->data_file,
- short_architecture,
- driver->version,
- ver);
- if (!W_ERROR_IS_OK(*perr)) {
- if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
- ver = -1;
- }
- goto err_exit;
- }
- }
- }
-
- if (driver->config_file && strlen(driver->config_file)) {
- if (!strequal(driver->config_file, driver->driver_path) &&
- !strequal(driver->config_file, driver->data_file)) {
-
- *perr = move_driver_file_to_download_area(ctx,
- conn,
- driver->config_file,
- short_architecture,
- driver->version,
- ver);
- if (!W_ERROR_IS_OK(*perr)) {
- if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
- ver = -1;
- }
- goto err_exit;
- }
- }
- }
-
- if (driver->help_file && strlen(driver->help_file)) {
- if (!strequal(driver->help_file, driver->driver_path) &&
- !strequal(driver->help_file, driver->data_file) &&
- !strequal(driver->help_file, driver->config_file)) {
-
- *perr = move_driver_file_to_download_area(ctx,
- conn,
- driver->help_file,
- short_architecture,
- driver->version,
- ver);
- if (!W_ERROR_IS_OK(*perr)) {
- if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
- ver = -1;
- }
- goto err_exit;
- }
- }
- }
-
- if (driver->dependent_files && driver->dependent_files->string) {
- for (i=0; driver->dependent_files->string[i]; i++) {
- if (!strequal(driver->dependent_files->string[i], driver->driver_path) &&
- !strequal(driver->dependent_files->string[i], driver->data_file) &&
- !strequal(driver->dependent_files->string[i], driver->config_file) &&
- !strequal(driver->dependent_files->string[i], driver->help_file)) {
- int j;
- for (j=0; j < i; j++) {
- if (strequal(driver->dependent_files->string[i], driver->dependent_files->string[j])) {
- goto NextDriver;
- }
- }
-
- *perr = move_driver_file_to_download_area(ctx,
- conn,
- driver->dependent_files->string[i],
- short_architecture,
- driver->version,
- ver);
- if (!W_ERROR_IS_OK(*perr)) {
- if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
- ver = -1;
- }
- goto err_exit;
- }
- }
- NextDriver: ;
- }
- }
-
- err_exit:
- TALLOC_FREE(smb_dname);
-
- if (conn != NULL) {
- vfs_ChDir(conn, oldcwd);
- conn_free(conn);
- }
-
- if (W_ERROR_EQUAL(*perr, WERR_OK)) {
- return WERR_OK;
- }
- if (ver == -1) {
- return WERR_UNKNOWN_PRINTER_DRIVER;
- }
- return (*perr);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static uint32 add_a_printer_driver_3(struct spoolss_AddDriverInfo3 *driver)
-{
- TALLOC_CTX *ctx = talloc_tos();
- int len, buflen;
- const char *architecture;
- char *directory = NULL;
- char *key = NULL;
- uint8 *buf;
- int i, ret;
- TDB_DATA dbuf;
-
- architecture = get_short_archi(driver->architecture);
- if (!architecture) {
- return (uint32)-1;
- }
-
- /* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
- * \\server is added in the rpc server layer.
- * It does make sense to NOT store the server's name in the printer TDB.
- */
-
- directory = talloc_asprintf(ctx, "\\print$\\%s\\%d\\",
- architecture, driver->version);
- if (!directory) {
- return (uint32)-1;
- }
-
-#define gen_full_driver_unc_path(ctx, directory, file) \
- do { \
- if (file && strlen(file)) { \
- file = talloc_asprintf(ctx, "%s%s", directory, file); \
- } else { \
- file = talloc_strdup(ctx, ""); \
- } \
- if (!file) { \
- return (uint32_t)-1; \
- } \
- } while (0);
-
- /* .inf files do not always list a file for each of the four standard files.
- * Don't prepend a path to a null filename, or client claims:
- * "The server on which the printer resides does not have a suitable
- * <printer driver name> printer driver installed. Click OK if you
- * wish to install the driver on your local machine."
- */
-
- gen_full_driver_unc_path(ctx, directory, driver->driver_path);
- gen_full_driver_unc_path(ctx, directory, driver->data_file);
- gen_full_driver_unc_path(ctx, directory, driver->config_file);
- gen_full_driver_unc_path(ctx, directory, driver->help_file);
-
- if (driver->dependent_files && driver->dependent_files->string) {
- for (i=0; driver->dependent_files->string[i]; i++) {
- gen_full_driver_unc_path(ctx, directory,
- driver->dependent_files->string[i]);
- }
- }
-
- key = talloc_asprintf(ctx, "%s%s/%d/%s", DRIVERS_PREFIX,
- architecture, driver->version, driver->driver_name);
- if (!key) {
- return (uint32)-1;
- }
-
- DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
-
- buf = NULL;
- len = buflen = 0;
-
- again:
- len = 0;
- len += tdb_pack(buf+len, buflen-len, "dffffffff",
- driver->version,
- driver->driver_name,
- driver->architecture,
- driver->driver_path,
- driver->data_file,
- driver->config_file,
- driver->help_file,
- driver->monitor_name ? driver->monitor_name : "",
- driver->default_datatype ? driver->default_datatype : "");
-
- if (driver->dependent_files && driver->dependent_files->string) {
- for (i=0; driver->dependent_files->string[i]; i++) {
- len += tdb_pack(buf+len, buflen-len, "f",
- driver->dependent_files->string[i]);
- }
- }
-
- if (len != buflen) {
- buf = (uint8 *)SMB_REALLOC(buf, len);
- if (!buf) {
- DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
- ret = -1;
- goto done;
- }
- buflen = len;
- goto again;
- }
-
- dbuf.dptr = buf;
- dbuf.dsize = len;
-
- ret = tdb_store_bystring(tdb_drivers, key, dbuf, TDB_REPLACE);
-
-done:
- if (ret)
- DEBUG(0,("add_a_printer_driver_3: Adding driver with key %s failed.\n", key ));
-
- SAFE_FREE(buf);
- return ret;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static uint32_t add_a_printer_driver_8(struct spoolss_DriverInfo8 *driver)
-{
- TALLOC_CTX *mem_ctx = talloc_new(talloc_tos());
- struct spoolss_AddDriverInfo3 info3;
- uint32_t ret;
-
- convert_level_8_to_level3(mem_ctx, &info3, driver);
-
- ret = add_a_printer_driver_3(&info3);
- talloc_free(mem_ctx);
-
- return ret;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR get_a_printer_driver_3_default(TALLOC_CTX *mem_ctx,
- struct spoolss_DriverInfo3 *info,
- const char *driver, const char *arch)
-{
- info->driver_name = talloc_strdup(mem_ctx, driver);
- if (!info->driver_name) {
- return WERR_NOMEM;
- }
-
- info->default_datatype = talloc_strdup(mem_ctx, "RAW");
- if (!info->default_datatype) {
- return WERR_NOMEM;
- }
-
- info->driver_path = talloc_strdup(mem_ctx, "");
- info->data_file = talloc_strdup(mem_ctx, "");
- info->config_file = talloc_strdup(mem_ctx, "");
- info->help_file = talloc_strdup(mem_ctx, "");
- if (!info->driver_path || !info->data_file || !info->config_file || !info->help_file) {
- return WERR_NOMEM;
- }
-
- return WERR_OK;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR get_a_printer_driver_3(TALLOC_CTX *mem_ctx,
- struct spoolss_DriverInfo3 *driver,
- const char *drivername, const char *arch,
- uint32_t version)
-{
- TDB_DATA dbuf;
- const char *architecture;
- int len = 0;
- int i;
- char *key = NULL;
- fstring name, driverpath, environment, datafile, configfile, helpfile, monitorname, defaultdatatype;
-
- architecture = get_short_archi(arch);
- if ( !architecture ) {
- return WERR_UNKNOWN_PRINTER_DRIVER;
- }
-
- /* Windows 4.0 (i.e. win9x) should always use a version of 0 */
-
- if ( strcmp( architecture, SPL_ARCH_WIN40 ) == 0 )
- version = 0;
-
- DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, drivername));
-
- if (asprintf(&key, "%s%s/%d/%s", DRIVERS_PREFIX,
- architecture, version, drivername) < 0) {
- return WERR_NOMEM;
- }
-
- dbuf = tdb_fetch_bystring(tdb_drivers, key);
- if (!dbuf.dptr) {
- SAFE_FREE(key);
- return WERR_UNKNOWN_PRINTER_DRIVER;
- }
-
- len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
- &driver->version,
- name,
- environment,
- driverpath,
- datafile,
- configfile,
- helpfile,
- monitorname,
- defaultdatatype);
-
- driver->driver_name = talloc_strdup(mem_ctx, name);
- driver->architecture = talloc_strdup(mem_ctx, environment);
- driver->driver_path = talloc_strdup(mem_ctx, driverpath);
- driver->data_file = talloc_strdup(mem_ctx, datafile);
- driver->config_file = talloc_strdup(mem_ctx, configfile);
- driver->help_file = talloc_strdup(mem_ctx, helpfile);
- driver->monitor_name = talloc_strdup(mem_ctx, monitorname);
- driver->default_datatype = talloc_strdup(mem_ctx, defaultdatatype);
-
- i=0;
-
- while (len < dbuf.dsize) {
-
- fstring file;
-
- driver->dependent_files = talloc_realloc(mem_ctx, driver->dependent_files, const char *, i+2);
- if (!driver->dependent_files ) {
- DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
- break;
- }
-
- len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
- &file);
-
- driver->dependent_files[i] = talloc_strdup(mem_ctx, file);
-
- i++;
- }
-
- if (driver->dependent_files)
- driver->dependent_files[i] = NULL;
-
- SAFE_FREE(dbuf.dptr);
- SAFE_FREE(key);
-
- if (len != dbuf.dsize) {
- return get_a_printer_driver_3_default(mem_ctx, driver, drivername, arch);
- }
-
- return WERR_OK;
-}
-
-/****************************************************************************
-****************************************************************************/
-int pack_devicemode(NT_DEVICEMODE *nt_devmode, uint8 *buf, int buflen)
-{
- int len = 0;
-
- len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
-
- if (!nt_devmode)
- return len;
-
- len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
- nt_devmode->devicename,
- nt_devmode->formname,
-
- nt_devmode->specversion,
- nt_devmode->driverversion,
- nt_devmode->size,
- nt_devmode->driverextra,
- nt_devmode->orientation,
- nt_devmode->papersize,
- nt_devmode->paperlength,
- nt_devmode->paperwidth,
- nt_devmode->scale,
- nt_devmode->copies,
- nt_devmode->defaultsource,
- nt_devmode->printquality,
- nt_devmode->color,
- nt_devmode->duplex,
- nt_devmode->yresolution,
- nt_devmode->ttoption,
- nt_devmode->collate,
- nt_devmode->logpixels,
-
- nt_devmode->fields,
- nt_devmode->bitsperpel,
- nt_devmode->pelswidth,
- nt_devmode->pelsheight,
- nt_devmode->displayflags,
- nt_devmode->displayfrequency,
- nt_devmode->icmmethod,
- nt_devmode->icmintent,
- nt_devmode->mediatype,
- nt_devmode->dithertype,
- nt_devmode->reserved1,
- nt_devmode->reserved2,
- nt_devmode->panningwidth,
- nt_devmode->panningheight,
- nt_devmode->nt_dev_private);
-
- if (nt_devmode->nt_dev_private) {
- len += tdb_pack(buf+len, buflen-len, "B",
- nt_devmode->driverextra,
- nt_devmode->nt_dev_private);
- }
-
- DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
-
- return len;
-}
-
-/****************************************************************************
- Pack all values in all printer keys
- ***************************************************************************/
-
-static int pack_values(NT_PRINTER_DATA *data, uint8 *buf, int buflen)
-{
- int len = 0;
- int i, j;
- struct regval_blob *val;
- struct regval_ctr *val_ctr;
- char *path = NULL;
- int num_values;
-
- if ( !data )
- return 0;
-
- /* loop over all keys */
-
- for ( i=0; i<data->num_keys; i++ ) {
- val_ctr = data->keys[i].values;
- num_values = regval_ctr_numvals( val_ctr );
-
- /* pack the keyname followed by a empty value */
-
- len += tdb_pack(buf+len, buflen-len, "pPdB",
- &data->keys[i].name,
- data->keys[i].name,
- REG_NONE,
- 0,
- NULL);
-
- /* now loop over all values */
-
- for ( j=0; j<num_values; j++ ) {
- /* pathname should be stored as <key>\<value> */
-
- val = regval_ctr_specific_value( val_ctr, j );
- if (asprintf(&path, "%s\\%s",
- data->keys[i].name,
- regval_name(val)) < 0) {
- return -1;
- }
-
- len += tdb_pack(buf+len, buflen-len, "pPdB",
- val,
- path,
- regval_type(val),
- regval_size(val),
- regval_data_p(val) );
-
- DEBUG(8,("specific: [%s], len: %d\n", regval_name(val), regval_size(val)));
- SAFE_FREE(path);
- }
-
- }
-
- /* terminator */
-
- len += tdb_pack(buf+len, buflen-len, "p", NULL);
-
- return len;
-}
-
-
-/****************************************************************************
- Delete a printer - this just deletes the printer info file, any open
- handles are not affected.
-****************************************************************************/
-
-uint32 del_a_printer(const char *sharename)
-{
- TDB_DATA kbuf;
- char *printdb_path = NULL;
- TALLOC_CTX *ctx = talloc_tos();
-
- kbuf = make_printer_tdbkey(ctx, sharename);
- tdb_delete(tdb_printers, kbuf);
-
- kbuf= make_printers_secdesc_tdbkey(ctx, sharename);
- tdb_delete(tdb_printers, kbuf);
-
- close_all_print_db();
-
- if (geteuid() == sec_initial_uid()) {
- if (asprintf(&printdb_path, "%s%s.tdb",
- cache_path("printing/"),
- sharename) < 0) {
- return (uint32)-1;
- }
- unlink(printdb_path);
- SAFE_FREE(printdb_path);
- }
-
- return 0;
-}
-
-/****************************************************************************
-****************************************************************************/
-static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
-{
- uint8 *buf;
- int buflen, len;
- int retlen;
- WERROR ret;
- TDB_DATA kbuf, dbuf;
-
- /*
- * in addprinter: no servername and the printer is the name
- * in setprinter: servername is \\server
- * and printer is \\server\\printer
- *
- * Samba manages only local printers.
- * we currently don't support things like i
- * path=\\other_server\printer
- *
- * We only store the printername, not \\server\printername
- */
-
- if ( info->servername[0] != '\0' ) {
- trim_string(info->printername, info->servername, NULL);
- trim_char(info->printername, '\\', '\0');
- info->servername[0]='\0';
- }
-
- /*
- * JFM: one day I'll forget.
- * below that's info->portname because that's the SAMBA sharename
- * and I made NT 'thinks' it's the portname
- * the info->sharename is the thing you can name when you add a printer
- * that's the short-name when you create shared printer for 95/98
- * So I've made a limitation in SAMBA: you can only have 1 printer model
- * behind a SAMBA share.
- */
-
- buf = NULL;
- buflen = 0;
-
- again:
- len = 0;
- len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
- info->attributes,
- info->priority,
- info->default_priority,
- info->starttime,
- info->untiltime,
- info->status,
- info->cjobs,
- info->averageppm,
- info->changeid,
- info->c_setprinter,
- info->setuptime,
- info->servername,
- info->printername,
- info->sharename,
- info->portname,
- info->drivername,
- info->comment,
- info->location,
- info->sepfile,
- info->printprocessor,
- info->datatype,
- info->parameters);
-
- len += pack_devicemode(info->devmode, buf+len, buflen-len);
- retlen = pack_values( info->data, buf+len, buflen-len );
- if (retlen == -1) {
- ret = WERR_NOMEM;
- goto done;
- }
- len += retlen;
-
- if (buflen != len) {
- buf = (uint8 *)SMB_REALLOC(buf, len);
- if (!buf) {
- DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
- ret = WERR_NOMEM;
- goto done;
- }
- buflen = len;
- goto again;
- }
-
- kbuf = make_printer_tdbkey(talloc_tos(), info->sharename );
-
- dbuf.dptr = buf;
- dbuf.dsize = len;
-
- ret = (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) == 0? WERR_OK : WERR_NOMEM);
-
-done:
- if (!W_ERROR_IS_OK(ret))
- DEBUG(8, ("error updating printer to tdb on disk\n"));
-
- SAFE_FREE(buf);
-
- DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
- info->sharename, info->drivername, info->portname, len));
-
- return ret;
-}
-
-
-/****************************************************************************
- Malloc and return an NT devicemode.
-****************************************************************************/
-
-NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
-{
-
- char adevice[MAXDEVICENAME];
- NT_DEVICEMODE *nt_devmode = SMB_MALLOC_P(NT_DEVICEMODE);
-
- if (nt_devmode == NULL) {
- DEBUG(0,("construct_nt_devicemode: malloc fail.\n"));
- return NULL;
- }
-
- ZERO_STRUCTP(nt_devmode);
-
- slprintf(adevice, sizeof(adevice), "%s", default_devicename);
- fstrcpy(nt_devmode->devicename, adevice);
-
- fstrcpy(nt_devmode->formname, "Letter");
-
- nt_devmode->specversion = DMSPEC_NT4_AND_ABOVE;
- nt_devmode->driverversion = 0x0400;
- nt_devmode->size = 0x00DC;
- nt_devmode->driverextra = 0x0000;
- nt_devmode->fields = DEVMODE_FORMNAME |
- DEVMODE_TTOPTION |
- DEVMODE_PRINTQUALITY |
- DEVMODE_DEFAULTSOURCE |
- DEVMODE_COPIES |
- DEVMODE_SCALE |
- DEVMODE_PAPERSIZE |
- DEVMODE_ORIENTATION;
- nt_devmode->orientation = DMORIENT_PORTRAIT;
- nt_devmode->papersize = DMPAPER_LETTER;
- nt_devmode->paperlength = 0;
- nt_devmode->paperwidth = 0;
- nt_devmode->scale = 0x64;
- nt_devmode->copies = 1;
- nt_devmode->defaultsource = DMBIN_FORMSOURCE;
- nt_devmode->printquality = DMRES_HIGH; /* 0x0258 */
- nt_devmode->color = DMRES_MONOCHROME;
- nt_devmode->duplex = DMDUP_SIMPLEX;
- nt_devmode->yresolution = 0;
- nt_devmode->ttoption = DMTT_SUBDEV;
- nt_devmode->collate = DMCOLLATE_FALSE;
- nt_devmode->icmmethod = 0;
- nt_devmode->icmintent = 0;
- nt_devmode->mediatype = 0;
- nt_devmode->dithertype = 0;
-
- /* non utilisés par un driver d'imprimante */
- nt_devmode->logpixels = 0;
- nt_devmode->bitsperpel = 0;
- nt_devmode->pelswidth = 0;
- nt_devmode->pelsheight = 0;
- nt_devmode->displayflags = 0;
- nt_devmode->displayfrequency = 0;
- nt_devmode->reserved1 = 0;
- nt_devmode->reserved2 = 0;
- nt_devmode->panningwidth = 0;
- nt_devmode->panningheight = 0;
-
- nt_devmode->nt_dev_private = NULL;
- return nt_devmode;
-}
-
-/****************************************************************************
- Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
-****************************************************************************/
-
-void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
-{
- NT_DEVICEMODE *nt_devmode = *devmode_ptr;
-
- if(nt_devmode == NULL)
- return;
-
- DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
-
- SAFE_FREE(nt_devmode->nt_dev_private);
- SAFE_FREE(*devmode_ptr);
-}
-
-/****************************************************************************
- Clean up and deallocate a (maybe partially) allocated NT_PRINTER_INFO_LEVEL_2.
-****************************************************************************/
-
-static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr)
-{
- NT_PRINTER_INFO_LEVEL_2 *info = *info_ptr;
-
- if ( !info )
- return;
-
- free_nt_devicemode(&info->devmode);
-
- TALLOC_FREE( *info_ptr );
-}
-
-
-/****************************************************************************
-****************************************************************************/
-int unpack_devicemode(NT_DEVICEMODE **nt_devmode, const uint8 *buf, int buflen)
-{
- int len = 0;
- int extra_len = 0;
- NT_DEVICEMODE devmode;
-
- ZERO_STRUCT(devmode);
-
- len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
-
- if (!*nt_devmode) return len;
-
- len += tdb_unpack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
- devmode.devicename,
- devmode.formname,
-
- &devmode.specversion,
- &devmode.driverversion,
- &devmode.size,
- &devmode.driverextra,
- &devmode.orientation,
- &devmode.papersize,
- &devmode.paperlength,
- &devmode.paperwidth,
- &devmode.scale,
- &devmode.copies,
- &devmode.defaultsource,
- &devmode.printquality,
- &devmode.color,
- &devmode.duplex,
- &devmode.yresolution,
- &devmode.ttoption,
- &devmode.collate,
- &devmode.logpixels,
-
- &devmode.fields,
- &devmode.bitsperpel,
- &devmode.pelswidth,
- &devmode.pelsheight,
- &devmode.displayflags,
- &devmode.displayfrequency,
- &devmode.icmmethod,
- &devmode.icmintent,
- &devmode.mediatype,
- &devmode.dithertype,
- &devmode.reserved1,
- &devmode.reserved2,
- &devmode.panningwidth,
- &devmode.panningheight,
- &devmode.nt_dev_private);
-
- if (devmode.nt_dev_private) {
- /* the len in tdb_unpack is an int value and
- * devmode.driverextra is only a short
- */
- len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.nt_dev_private);
- devmode.driverextra=(uint16)extra_len;
-
- /* check to catch an invalid TDB entry so we don't segfault */
- if (devmode.driverextra == 0) {
- devmode.nt_dev_private = NULL;
- }
- }
-
- *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
- if (!*nt_devmode) {
- SAFE_FREE(devmode.nt_dev_private);
- return -1;
- }
-
- DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
- if (devmode.nt_dev_private)
- DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
-
- return len;
-}
-
-/****************************************************************************
- Allocate and initialize a new slot.
-***************************************************************************/
-
-int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
-{
- NT_PRINTER_KEY *d;
- int key_index;
-
- if ( !name || !data )
- return -1;
-
- /* allocate another slot in the NT_PRINTER_KEY array */
-
- if ( !(d = TALLOC_REALLOC_ARRAY( data, data->keys, NT_PRINTER_KEY, data->num_keys+1)) ) {
- DEBUG(0,("add_new_printer_key: Realloc() failed!\n"));
- return -1;
- }
-
- data->keys = d;
-
- key_index = data->num_keys;
-
- /* initialze new key */
-
- data->keys[key_index].name = talloc_strdup( data, name );
-
- if ( !(data->keys[key_index].values = TALLOC_ZERO_P( data, struct regval_ctr )) )
- return -1;
-
- data->num_keys++;
-
- DEBUG(10,("add_new_printer_key: Inserted new data key [%s]\n", name ));
-
- return key_index;
-}
-
-/****************************************************************************
- search for a registry key name in the existing printer data
- ***************************************************************************/
-
-int delete_printer_key( NT_PRINTER_DATA *data, const char *name )
-{
- int i;
-
- for ( i=0; i<data->num_keys; i++ ) {
- if ( strequal( data->keys[i].name, name ) ) {
-
- /* cleanup memory */
-
- TALLOC_FREE( data->keys[i].name );
- TALLOC_FREE( data->keys[i].values );
-
- /* if not the end of the array, move remaining elements down one slot */
-
- data->num_keys--;
- if ( data->num_keys && (i < data->num_keys) )
- memmove( &data->keys[i], &data->keys[i+1], sizeof(NT_PRINTER_KEY)*(data->num_keys-i) );
-
- break;
- }
- }
-
-
- return data->num_keys;
-}
-
-/****************************************************************************
- search for a registry key name in the existing printer data
- ***************************************************************************/
-
-int lookup_printerkey( NT_PRINTER_DATA *data, const char *name )
-{
- int key_index = -1;
- int i;
-
- if ( !data || !name )
- return -1;
-
- DEBUG(12,("lookup_printerkey: Looking for [%s]\n", name));
-
- /* loop over all existing keys */
-
- for ( i=0; i<data->num_keys; i++ ) {
- if ( strequal(data->keys[i].name, name) ) {
- DEBUG(12,("lookup_printerkey: Found [%s]!\n", name));
- key_index = i;
- break;
-
- }
- }
-
- return key_index;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys )
-{
- int i, j;
- int key_len;
- int num_subkeys = 0;
- char *p;
- fstring *subkeys_ptr = NULL;
- fstring subkeyname;
-
- *subkeys = NULL;
-
- if ( !data )
- return 0;
-
- if ( !key )
- return -1;
-
- /* special case of asking for the top level printer data registry key names */
-
- if ( strlen(key) == 0 ) {
- for ( i=0; i<data->num_keys; i++ ) {
-
- /* found a match, so allocate space and copy the name */
-
- if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
- DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
- num_subkeys+1));
- return -1;
- }
-
- fstrcpy( subkeys_ptr[num_subkeys], data->keys[i].name );
- num_subkeys++;
- }
-
- goto done;
- }
-
- /* asking for the subkeys of some key */
- /* subkey paths are stored in the key name using '\' as the delimiter */
-
- for ( i=0; i<data->num_keys; i++ ) {
- if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) {
-
- /* if we found the exact key, then break */
- key_len = strlen( key );
- if ( strlen(data->keys[i].name) == key_len )
- break;
-
- /* get subkey path */
-
- p = data->keys[i].name + key_len;
- if ( *p == '\\' )
- p++;
- fstrcpy( subkeyname, p );
- if ( (p = strchr( subkeyname, '\\' )) )
- *p = '\0';
-
- /* don't add a key more than once */
-
- for ( j=0; j<num_subkeys; j++ ) {
- if ( strequal( subkeys_ptr[j], subkeyname ) )
- break;
- }
-
- if ( j != num_subkeys )
- continue;
-
- /* found a match, so allocate space and copy the name */
-
- if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
- DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
- num_subkeys+1));
- return 0;
- }
-
- fstrcpy( subkeys_ptr[num_subkeys], subkeyname );
- num_subkeys++;
- }
-
- }
-
- /* return error if the key was not found */
-
- if ( i == data->num_keys ) {
- SAFE_FREE(subkeys_ptr);
- return -1;
- }
-
-done:
- /* tag off the end */
-
- if (num_subkeys)
- fstrcpy(subkeys_ptr[num_subkeys], "" );
-
- *subkeys = subkeys_ptr;
-
- return num_subkeys;
-}
-
-#ifdef HAVE_ADS
-static void map_sz_into_ctr(struct regval_ctr *ctr, const char *val_name,
- const char *sz)
-{
- regval_ctr_delvalue(ctr, val_name);
- regval_ctr_addvalue_sz(ctr, val_name, sz);
-}
-
-static void map_dword_into_ctr(struct regval_ctr *ctr, const char *val_name,
- uint32 dword)
-{
- regval_ctr_delvalue(ctr, val_name);
- regval_ctr_addvalue(ctr, val_name, REG_DWORD,
- (char *) &dword, sizeof(dword));
-}
-
-static void map_bool_into_ctr(struct regval_ctr *ctr, const char *val_name,
- bool b)
-{
- uint8 bin_bool = (b ? 1 : 0);
- regval_ctr_delvalue(ctr, val_name);
- regval_ctr_addvalue(ctr, val_name, REG_BINARY,
- (char *) &bin_bool, sizeof(bin_bool));
-}
-
-static void map_single_multi_sz_into_ctr(struct regval_ctr *ctr, const char *val_name,
- const char *multi_sz)
-{
- const char *a[2];
-
- a[0] = multi_sz;
- a[1] = NULL;
-
- regval_ctr_delvalue(ctr, val_name);
- regval_ctr_addvalue_multi_sz(ctr, val_name, a);
-}
-
-/****************************************************************************
- * Map the NT_PRINTER_INFO_LEVEL_2 data into DsSpooler keys for publishing.
- *
- * @param info2 NT_PRINTER_INFO_LEVEL_2 describing printer - gets modified
- * @return bool indicating success or failure
- ***************************************************************************/
-
-static bool map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
-{
- struct regval_ctr *ctr = NULL;
- fstring longname;
- const char *dnssuffix;
- char *allocated_string = NULL;
- const char *ascii_str;
- int i;
-
- if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
- i = add_new_printer_key(info2->data, SPOOL_DSSPOOLER_KEY);
- ctr = info2->data->keys[i].values;
-
- map_sz_into_ctr(ctr, SPOOL_REG_PRINTERNAME, info2->sharename);
- map_sz_into_ctr(ctr, SPOOL_REG_SHORTSERVERNAME, global_myname());
-
- /* we make the assumption that the netbios name is the same
- as the DNS name sinc ethe former will be what we used to
- join the domain */
-
- dnssuffix = get_mydnsdomname(talloc_tos());
- if (dnssuffix && *dnssuffix) {
- fstr_sprintf( longname, "%s.%s", global_myname(), dnssuffix );
- } else {
- fstrcpy( longname, global_myname() );
- }
-
- map_sz_into_ctr(ctr, SPOOL_REG_SERVERNAME, longname);
-
- if (asprintf(&allocated_string, "\\\\%s\\%s", longname, info2->sharename) == -1) {
- return false;
- }
- map_sz_into_ctr(ctr, SPOOL_REG_UNCNAME, allocated_string);
- SAFE_FREE(allocated_string);
-
- map_dword_into_ctr(ctr, SPOOL_REG_VERSIONNUMBER, 4);
- map_sz_into_ctr(ctr, SPOOL_REG_DRIVERNAME, info2->drivername);
- map_sz_into_ctr(ctr, SPOOL_REG_LOCATION, info2->location);
- map_sz_into_ctr(ctr, SPOOL_REG_DESCRIPTION, info2->comment);
- map_single_multi_sz_into_ctr(ctr, SPOOL_REG_PORTNAME, info2->portname);
- map_sz_into_ctr(ctr, SPOOL_REG_PRINTSEPARATORFILE, info2->sepfile);
- map_dword_into_ctr(ctr, SPOOL_REG_PRINTSTARTTIME, info2->starttime);
- map_dword_into_ctr(ctr, SPOOL_REG_PRINTENDTIME, info2->untiltime);
- map_dword_into_ctr(ctr, SPOOL_REG_PRIORITY, info2->priority);
-
- map_bool_into_ctr(ctr, SPOOL_REG_PRINTKEEPPRINTEDJOBS,
- (info2->attributes &
- PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
-
- switch (info2->attributes & 0x3) {
- case 0:
- ascii_str = SPOOL_REGVAL_PRINTWHILESPOOLING;
- break;
- case 1:
- ascii_str = SPOOL_REGVAL_PRINTAFTERSPOOLED;
- break;
- case 2:
- ascii_str = SPOOL_REGVAL_PRINTDIRECT;
- break;
- default:
- ascii_str = "unknown";
- }
- map_sz_into_ctr(ctr, SPOOL_REG_PRINTSPOOLING, ascii_str);
-
- return True;
-}
-
-/*****************************************************************
- ****************************************************************/
-
-static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2,
- struct GUID guid)
-{
- int i;
- struct regval_ctr *ctr=NULL;
-
- /* find the DsSpooler key */
- if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
- i = add_new_printer_key(info2->data, SPOOL_DSSPOOLER_KEY);
- ctr = info2->data->keys[i].values;
-
- regval_ctr_delvalue(ctr, "objectGUID");
-
- /* We used to store this as a REG_BINARY but that causes
- Vista to whine */
-
- regval_ctr_addvalue_sz(ctr, "objectGUID",
- GUID_string(talloc_tos(), &guid));
-}
-
-static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
- NT_PRINTER_INFO_LEVEL *printer)
-{
- ADS_STATUS ads_rc;
- LDAPMessage *res;
- char *prt_dn = NULL, *srv_dn, *srv_cn_0, *srv_cn_escaped, *sharename_escaped;
- char *srv_dn_utf8, **srv_cn_utf8;
- TALLOC_CTX *ctx;
- ADS_MODLIST mods;
- const char *attrs[] = {"objectGUID", NULL};
- struct GUID guid;
- WERROR win_rc = WERR_OK;
- size_t converted_size;
-
- /* build the ads mods */
- ctx = talloc_init("nt_printer_publish_ads");
- if (ctx == NULL) {
- return WERR_NOMEM;
- }
-
- DEBUG(5, ("publishing printer %s\n", printer->info_2->printername));
-
- /* figure out where to publish */
- ads_find_machine_acct(ads, &res, global_myname());
-
- /* We use ldap_get_dn here as we need the answer
- * in utf8 to call ldap_explode_dn(). JRA. */
-
- srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ldap.ld, (LDAPMessage *)res);
- if (!srv_dn_utf8) {
- TALLOC_FREE(ctx);
- return WERR_SERVER_UNAVAILABLE;
- }
- ads_msgfree(ads, res);
- srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1);
- if (!srv_cn_utf8) {
- TALLOC_FREE(ctx);
- ldap_memfree(srv_dn_utf8);
- return WERR_SERVER_UNAVAILABLE;
- }
- /* Now convert to CH_UNIX. */
- if (!pull_utf8_talloc(ctx, &srv_dn, srv_dn_utf8, &converted_size)) {
- TALLOC_FREE(ctx);
- ldap_memfree(srv_dn_utf8);
- ldap_memfree(srv_cn_utf8);
- return WERR_SERVER_UNAVAILABLE;
- }
- if (!pull_utf8_talloc(ctx, &srv_cn_0, srv_cn_utf8[0], &converted_size)) {
- TALLOC_FREE(ctx);
- ldap_memfree(srv_dn_utf8);
- ldap_memfree(srv_cn_utf8);
- TALLOC_FREE(srv_dn);
- return WERR_SERVER_UNAVAILABLE;
- }
-
- ldap_memfree(srv_dn_utf8);
- ldap_memfree(srv_cn_utf8);
-
- srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0);
- if (!srv_cn_escaped) {
- TALLOC_FREE(ctx);
- return WERR_SERVER_UNAVAILABLE;
- }
- sharename_escaped = escape_rdn_val_string_alloc(printer->info_2->sharename);
- if (!sharename_escaped) {
- SAFE_FREE(srv_cn_escaped);
- TALLOC_FREE(ctx);
- return WERR_SERVER_UNAVAILABLE;
- }
-
- prt_dn = talloc_asprintf(ctx, "cn=%s-%s,%s", srv_cn_escaped, sharename_escaped, srv_dn);
-
- SAFE_FREE(srv_cn_escaped);
- SAFE_FREE(sharename_escaped);
-
- mods = ads_init_mods(ctx);
-
- if (mods == NULL) {
- SAFE_FREE(prt_dn);
- TALLOC_FREE(ctx);
- return WERR_NOMEM;
- }
-
- get_local_printer_publishing_data(ctx, &mods, printer->info_2->data);
- ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME,
- printer->info_2->sharename);
-
- /* publish it */
- ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx, &mods);
- if (ads_rc.err.rc == LDAP_NO_SUCH_OBJECT) {
- int i;
- for (i=0; mods[i] != 0; i++)
- ;
- mods[i] = (LDAPMod *)-1;
- ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
- }
-
- if (!ADS_ERR_OK(ads_rc))
- DEBUG(3, ("error publishing %s: %s\n", printer->info_2->sharename, ads_errstr(ads_rc)));
-
- /* retreive the guid and store it locally */
- if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) {
- ZERO_STRUCT(guid);
- ads_pull_guid(ads, res, &guid);
- ads_msgfree(ads, res);
- store_printer_guid(printer->info_2, guid);
- win_rc = mod_a_printer(printer, 2);
- }
- TALLOC_FREE(ctx);
-
- return win_rc;
-}
-
-static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads,
- NT_PRINTER_INFO_LEVEL *printer)
-{
- ADS_STATUS ads_rc;
- LDAPMessage *res = NULL;
- char *prt_dn = NULL;
-
- DEBUG(5, ("unpublishing printer %s\n", printer->info_2->printername));
-
- /* remove the printer from the directory */
- ads_rc = ads_find_printer_on_server(ads, &res,
- printer->info_2->sharename, global_myname());
-
- if (ADS_ERR_OK(ads_rc) && res && ads_count_replies(ads, res)) {
- prt_dn = ads_get_dn(ads, talloc_tos(), res);
- if (!prt_dn) {
- ads_msgfree(ads, res);
- return WERR_NOMEM;
- }
- ads_rc = ads_del_dn(ads, prt_dn);
- TALLOC_FREE(prt_dn);
- }
-
- if (res) {
- ads_msgfree(ads, res);
- }
- return WERR_OK;
-}
-
-/****************************************************************************
- * Publish a printer in the directory
- *
- * @param snum describing printer service
- * @return WERROR indicating status of publishing
- ***************************************************************************/
-
-WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
-{
- ADS_STATUS ads_rc;
- ADS_STRUCT *ads = NULL;
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- WERROR win_rc;
-
- win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
- if (!W_ERROR_IS_OK(win_rc))
- goto done;
-
- switch (action) {
- case DSPRINT_PUBLISH:
- case DSPRINT_UPDATE:
- /* set the DsSpooler info and attributes */
- if (!(map_nt_printer_info2_to_dsspooler(printer->info_2))) {
- win_rc = WERR_NOMEM;
- goto done;
- }
-
- printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
- break;
- case DSPRINT_UNPUBLISH:
- printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
- break;
- default:
- win_rc = WERR_NOT_SUPPORTED;
- goto done;
- }
-
- win_rc = mod_a_printer(printer, 2);
- if (!W_ERROR_IS_OK(win_rc)) {
- DEBUG(3, ("err %d saving data\n", W_ERROR_V(win_rc)));
- goto done;
- }
-
- ads = ads_init(lp_realm(), lp_workgroup(), NULL);
- if (!ads) {
- DEBUG(3, ("ads_init() failed\n"));
- win_rc = WERR_SERVER_UNAVAILABLE;
- goto done;
- }
- setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
- SAFE_FREE(ads->auth.password);
- ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
- NULL, NULL);
-
- /* ads_connect() will find the DC for us */
- ads_rc = ads_connect(ads);
- if (!ADS_ERR_OK(ads_rc)) {
- DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
- win_rc = WERR_ACCESS_DENIED;
- goto done;
- }
-
- switch (action) {
- case DSPRINT_PUBLISH:
- case DSPRINT_UPDATE:
- win_rc = nt_printer_publish_ads(ads, printer);
- break;
- case DSPRINT_UNPUBLISH:
- win_rc = nt_printer_unpublish_ads(ads, printer);
- break;
- }
-
-done:
- free_a_printer(&printer, 2);
- ads_destroy(&ads);
- return win_rc;
-}
-
-WERROR check_published_printers(void)
-{
- ADS_STATUS ads_rc;
- ADS_STRUCT *ads = NULL;
- int snum;
- int n_services = lp_numservices();
- NT_PRINTER_INFO_LEVEL *printer = NULL;
-
- ads = ads_init(lp_realm(), lp_workgroup(), NULL);
- if (!ads) {
- DEBUG(3, ("ads_init() failed\n"));
- return WERR_SERVER_UNAVAILABLE;
- }
- setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
- SAFE_FREE(ads->auth.password);
- ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
- NULL, NULL);
-
- /* ads_connect() will find the DC for us */
- ads_rc = ads_connect(ads);
- if (!ADS_ERR_OK(ads_rc)) {
- DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
- ads_destroy(&ads);
- ads_kdestroy("MEMORY:prtpub_cache");
- return WERR_ACCESS_DENIED;
- }
-
- for (snum = 0; snum < n_services; snum++) {
- if (!(lp_snum_ok(snum) && lp_print_ok(snum)))
- continue;
-
- if (W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2,
- lp_servicename(snum))) &&
- (printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED))
- nt_printer_publish_ads(ads, printer);
-
- free_a_printer(&printer, 2);
- }
-
- ads_destroy(&ads);
- ads_kdestroy("MEMORY:prtpub_cache");
- return WERR_OK;
-}
-
-bool is_printer_published(Printer_entry *print_hnd, int snum,
- struct GUID *guid)
-{
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- struct regval_ctr *ctr;
- struct regval_blob *guid_val;
- WERROR win_rc;
- int i;
- bool ret = False;
- DATA_BLOB blob;
-
- win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
-
- if (!W_ERROR_IS_OK(win_rc) ||
- !(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) ||
- ((i = lookup_printerkey(printer->info_2->data, SPOOL_DSSPOOLER_KEY)) < 0) ||
- !(ctr = printer->info_2->data->keys[i].values) ||
- !(guid_val = regval_ctr_getvalue(ctr, "objectGUID")))
- {
- free_a_printer(&printer, 2);
- return False;
- }
-
- /* fetching printer guids really ought to be a separate function. */
-
- if ( guid ) {
- char *guid_str;
-
- /* We used to store the guid as REG_BINARY, then swapped
- to REG_SZ for Vista compatibility so check for both */
-
- switch ( regval_type(guid_val) ){
- case REG_SZ:
- blob = data_blob_const(regval_data_p(guid_val),
- regval_size(guid_val));
- pull_reg_sz(talloc_tos(), NULL, &blob, (const char **)&guid_str);
- ret = NT_STATUS_IS_OK(GUID_from_string( guid_str, guid ));
- talloc_free(guid_str);
- break;
- case REG_BINARY:
- if ( regval_size(guid_val) != sizeof(struct GUID) ) {
- ret = False;
- break;
- }
- memcpy(guid, regval_data_p(guid_val), sizeof(struct GUID));
- break;
- default:
- DEBUG(0,("is_printer_published: GUID value stored as "
- "invaluid type (%d)\n", regval_type(guid_val) ));
- break;
- }
- }
-
- free_a_printer(&printer, 2);
- return ret;
-}
-#else
-WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
-{
- return WERR_OK;
-}
-
-WERROR check_published_printers(void)
-{
- return WERR_OK;
-}
-
-bool is_printer_published(Printer_entry *print_hnd, int snum,
- struct GUID *guid)
-{
- return False;
-}
-#endif /* HAVE_ADS */
-
-/****************************************************************************
- ***************************************************************************/
-
-WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
-{
- NT_PRINTER_DATA *data;
- int i;
- int removed_keys = 0;
- int empty_slot;
-
- data = p2->data;
- empty_slot = data->num_keys;
-
- if ( !key )
- return WERR_INVALID_PARAM;
-
- /* remove all keys */
-
- if ( !strlen(key) ) {
-
- TALLOC_FREE( data );
-
- p2->data = NULL;
-
- DEBUG(8,("delete_all_printer_data: Removed all Printer Data from printer [%s]\n",
- p2->printername ));
-
- return WERR_OK;
- }
-
- /* remove a specific key (and all subkeys) */
-
- for ( i=0; i<data->num_keys; i++ ) {
- if ( StrnCaseCmp( data->keys[i].name, key, strlen(key)) == 0 ) {
- DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n",
- data->keys[i].name));
-
- TALLOC_FREE( data->keys[i].name );
- TALLOC_FREE( data->keys[i].values );
-
- /* mark the slot as empty */
-
- ZERO_STRUCTP( &data->keys[i] );
- }
- }
-
- /* find the first empty slot */
-
- for ( i=0; i<data->num_keys; i++ ) {
- if ( !data->keys[i].name ) {
- empty_slot = i;
- removed_keys++;
- break;
- }
- }
-
- if ( i == data->num_keys )
- /* nothing was removed */
- return WERR_INVALID_PARAM;
-
- /* move everything down */
-
- for ( i=empty_slot+1; i<data->num_keys; i++ ) {
- if ( data->keys[i].name ) {
- memcpy( &data->keys[empty_slot], &data->keys[i], sizeof(NT_PRINTER_KEY) );
- ZERO_STRUCTP( &data->keys[i] );
- empty_slot++;
- removed_keys++;
- }
- }
-
- /* update count */
-
- data->num_keys -= removed_keys;
-
- /* sanity check to see if anything is left */
-
- if ( !data->num_keys ) {
- DEBUG(8,("delete_all_printer_data: No keys left for printer [%s]\n", p2->printername ));
-
- SAFE_FREE( data->keys );
- ZERO_STRUCTP( data );
- }
-
- return WERR_OK;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
-{
- WERROR result = WERR_OK;
- int key_index;
-
- /* we must have names on non-zero length */
-
- if ( !key || !*key|| !value || !*value )
- return WERR_INVALID_NAME;
-
- /* find the printer key first */
-
- key_index = lookup_printerkey( p2->data, key );
- if ( key_index == -1 )
- return WERR_OK;
-
- /* make sure the value exists so we can return the correct error code */
-
- if ( !regval_ctr_getvalue( p2->data->keys[key_index].values, value ) )
- return WERR_BADFILE;
-
- regval_ctr_delvalue( p2->data->keys[key_index].values, value );
-
- DEBUG(8,("delete_printer_data: Removed key => [%s], value => [%s]\n",
- key, value ));
-
- return result;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value,
- uint32 type, uint8 *data, int real_len )
-{
- WERROR result = WERR_OK;
- int key_index;
-
- /* we must have names on non-zero length */
-
- if ( !key || !*key|| !value || !*value )
- return WERR_INVALID_NAME;
-
- /* find the printer key first */
-
- key_index = lookup_printerkey( p2->data, key );
- if ( key_index == -1 )
- key_index = add_new_printer_key( p2->data, key );
-
- if ( key_index == -1 )
- return WERR_NOMEM;
-
- regval_ctr_addvalue( p2->data->keys[key_index].values, value,
- type, (const char *)data, real_len );
-
- DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n",
- key, value, type, real_len ));
-
- return result;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-struct regval_blob* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
-{
- int key_index;
-
- if ( (key_index = lookup_printerkey( p2->data, key )) == -1 )
- return NULL;
-
- DEBUG(8,("get_printer_data: Attempting to lookup key => [%s], value => [%s]\n",
- key, value ));
-
- return regval_ctr_getvalue( p2->data->keys[key_index].values, value );
-}
-
-/****************************************************************************
- Unpack a list of registry values frem the TDB
- ***************************************************************************/
-
-static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int buflen)
-{
- int len = 0;
- uint32 type;
- fstring string;
- const char *valuename = NULL;
- const char *keyname = NULL;
- char *str;
- int size;
- uint8 *data_p;
- struct regval_blob *regval_p;
- int key_index;
-
- /* add the "PrinterDriverData" key first for performance reasons */
-
- add_new_printer_key( printer_data, SPOOL_PRINTERDATA_KEY );
-
- /* loop and unpack the rest of the registry values */
-
- while ( True ) {
-
- /* check to see if there are any more registry values */
-
- regval_p = NULL;
- len += tdb_unpack(buf+len, buflen-len, "p", ®val_p);
- if ( !regval_p )
- break;
-
- /* unpack the next regval */
-
- len += tdb_unpack(buf+len, buflen-len, "fdB",
- string,
- &type,
- &size,
- &data_p);
-
- /* lookup for subkey names which have a type of REG_NONE */
- /* there's no data with this entry */
-
- if ( type == REG_NONE ) {
- if ( (key_index=lookup_printerkey( printer_data, string)) == -1 )
- add_new_printer_key( printer_data, string );
- continue;
- }
-
- /*
- * break of the keyname from the value name.
- * Valuenames can have embedded '\'s so be careful.
- * only support one level of keys. See the
- * "Konica Fiery S300 50C-K v1.1. enu" 2k driver.
- * -- jerry
- */
-
- str = strchr_m( string, '\\');
-
- /* Put in "PrinterDriverData" is no key specified */
-
- if ( !str ) {
- keyname = SPOOL_PRINTERDATA_KEY;
- valuename = string;
- }
- else {
- *str = '\0';
- keyname = string;
- valuename = str+1;
- }
-
- /* see if we need a new key */
-
- if ( (key_index=lookup_printerkey( printer_data, keyname )) == -1 )
- key_index = add_new_printer_key( printer_data, keyname );
-
- if ( key_index == -1 ) {
- DEBUG(0,("unpack_values: Failed to allocate a new key [%s]!\n",
- keyname));
- break;
- }
-
- DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size));
-
- /* Vista doesn't like unknown REG_BINARY values in DsSpooler.
- Thanks to Martin Zielinski for the hint. */
-
- if ( type == REG_BINARY &&
- strequal( keyname, SPOOL_DSSPOOLER_KEY ) &&
- strequal( valuename, "objectGUID" ) )
- {
- struct GUID guid;
-
- /* convert the GUID to a UNICODE string */
-
- memcpy( &guid, data_p, sizeof(struct GUID) );
-
- regval_ctr_addvalue_sz(printer_data->keys[key_index].values,
- valuename,
- GUID_string(talloc_tos(), &guid));
-
- } else {
- /* add the value */
-
- regval_ctr_addvalue( printer_data->keys[key_index].values,
- valuename, type, (const char *)data_p,
- size );
- }
-
- SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */
-
- }
-
- return len;
-}
-
-/****************************************************************************
- ***************************************************************************/
-
-static char *last_from;
-static char *last_to;
-
-static const char *get_last_from(void)
-{
- if (!last_from) {
- return "";
- }
- return last_from;
-}
-
-static const char *get_last_to(void)
-{
- if (!last_to) {
- return "";
- }
- return last_to;
-}
-
-static bool set_last_from_to(const char *from, const char *to)
-{
- char *orig_from = last_from;
- char *orig_to = last_to;
-
- last_from = SMB_STRDUP(from);
- last_to = SMB_STRDUP(to);
-
- SAFE_FREE(orig_from);
- SAFE_FREE(orig_to);
-
- if (!last_from || !last_to) {
- SAFE_FREE(last_from);
- SAFE_FREE(last_to);
- return false;
- }
- return true;
-}
-
-static void map_to_os2_driver(fstring drivername)
-{
- char *mapfile = lp_os2_driver_map();
- char **lines = NULL;
- int numlines = 0;
- int i;
-
- if (!strlen(drivername))
- return;
-
- if (!*mapfile)
- return;
-
- if (strequal(drivername,get_last_from())) {
- DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",
- drivername,get_last_to()));
- fstrcpy(drivername,get_last_to());
- return;
- }
-
- lines = file_lines_load(mapfile, &numlines,0,NULL);
- if (numlines == 0 || lines == NULL) {
- DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
- TALLOC_FREE(lines);
- return;
- }
-
- DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
-
- for( i = 0; i < numlines; i++) {
- char *nt_name = lines[i];
- char *os2_name = strchr(nt_name,'=');
-
- if (!os2_name)
- continue;
-
- *os2_name++ = 0;
-
- while (isspace(*nt_name))
- nt_name++;
-
- if (!*nt_name || strchr("#;",*nt_name))
- continue;
-
- {
- int l = strlen(nt_name);
- while (l && isspace(nt_name[l-1])) {
- nt_name[l-1] = 0;
- l--;
- }
- }
-
- while (isspace(*os2_name))
- os2_name++;
-
- {
- int l = strlen(os2_name);
- while (l && isspace(os2_name[l-1])) {
- os2_name[l-1] = 0;
- l--;
- }
- }
-
- if (strequal(nt_name,drivername)) {
- DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
- set_last_from_to(drivername,os2_name);
- fstrcpy(drivername,os2_name);
- TALLOC_FREE(lines);
- return;
- }
- }
-
- TALLOC_FREE(lines);
-}
-
-/****************************************************************************
- Get a default printer info 2 struct.
-****************************************************************************/
-
-static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info,
- const char *servername,
- const char* sharename,
- bool get_loc_com)
-{
- int snum = lp_servicenumber(sharename);
-
- slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername);
- slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
- servername, sharename);
- fstrcpy(info->sharename, sharename);
- fstrcpy(info->portname, SAMBA_PRINTER_PORT_NAME);
-
- /* by setting the driver name to an empty string, a local NT admin
- can now run the **local** APW to install a local printer driver
- for a Samba shared printer in 2.2. Without this, drivers **must** be
- installed on the Samba server for NT clients --jerry */
-#if 0 /* JERRY --do not uncomment-- */
- if (!*info->drivername)
- fstrcpy(info->drivername, "NO DRIVER AVAILABLE FOR THIS PRINTER");
-#endif
-
-
- DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info->drivername));
-
- strlcpy(info->comment, "", sizeof(info->comment));
- fstrcpy(info->printprocessor, "winprint");
- fstrcpy(info->datatype, "RAW");
-
-#ifdef HAVE_CUPS
- if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
- /* Pull the location and comment strings from cups if we don't
- already have one */
- if ( !strlen(info->location) || !strlen(info->comment) ) {
- char *comment = NULL;
- char *location = NULL;
- if (cups_pull_comment_location(info, info->sharename,
- &comment, &location)) {
- strlcpy(info->comment, comment, sizeof(info->comment));
- fstrcpy(info->location, location);
- TALLOC_FREE(comment);
- TALLOC_FREE(location);
- }
- }
- }
-#endif
-
- info->attributes = PRINTER_ATTRIBUTE_SAMBA;
-
- info->starttime = 0; /* Minutes since 12:00am GMT */
- info->untiltime = 0; /* Minutes since 12:00am GMT */
- info->priority = 1;
- info->default_priority = 1;
- info->setuptime = (uint32)time(NULL);
-
- /*
- * I changed this as I think it is better to have a generic
- * DEVMODE than to crash Win2k explorer.exe --jerry
- * See the HP Deskjet 990c Win2k drivers for an example.
- *
- * However the default devmode appears to cause problems
- * with the HP CLJ 8500 PCL driver. Hence the addition of
- * the "default devmode" parameter --jerry 22/01/2002
- */
-
- if (lp_default_devmode(snum)) {
- if ((info->devmode = construct_nt_devicemode(info->printername)) == NULL) {
- goto fail;
- }
- } else {
- info->devmode = NULL;
- }
-
- if (!nt_printing_getsec(info, sharename, &info->secdesc_buf)) {
- goto fail;
- }
-
- info->data = TALLOC_ZERO_P(info, NT_PRINTER_DATA);
- if (!info->data) {
- goto fail;
- }
-
- add_new_printer_key(info->data, SPOOL_PRINTERDATA_KEY);
-
- return WERR_OK;
-
-fail:
- if (info->devmode)
- free_nt_devicemode(&info->devmode);
-
- return WERR_ACCESS_DENIED;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info,
- const char *servername,
- const char *sharename,
- bool get_loc_com)
-{
- int len = 0;
- int snum = lp_servicenumber(sharename);
- TDB_DATA kbuf, dbuf;
- fstring printername;
- char adevice[MAXDEVICENAME];
- char *comment = NULL;
-
- kbuf = make_printer_tdbkey(talloc_tos(), sharename);
-
- dbuf = tdb_fetch(tdb_printers, kbuf);
- if (!dbuf.dptr) {
- return get_a_printer_2_default(info, servername,
- sharename, get_loc_com);
- }
-
- len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
- &info->attributes,
- &info->priority,
- &info->default_priority,
- &info->starttime,
- &info->untiltime,
- &info->status,
- &info->cjobs,
- &info->averageppm,
- &info->changeid,
- &info->c_setprinter,
- &info->setuptime,
- info->servername,
- info->printername,
- info->sharename,
- info->portname,
- info->drivername,
- &comment,
- info->location,
- info->sepfile,
- info->printprocessor,
- info->datatype,
- info->parameters);
-
- if (comment) {
- strlcpy(info->comment, comment, sizeof(info->comment));
- SAFE_FREE(comment);
- }
-
- /* Samba has to have shared raw drivers. */
- info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
- info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
-
- /* Restore the stripped strings. */
- slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername);
-
- if ( lp_force_printername(snum) ) {
- slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, sharename );
- } else {
- slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, info->printername);
- }
-
- fstrcpy(info->printername, printername);
-
-#ifdef HAVE_CUPS
- if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
- /* Pull the location and comment strings from cups if we don't
- already have one */
- if ( !strlen(info->location) || !strlen(info->comment) ) {
- char *location = NULL;
- comment = NULL;
- if (cups_pull_comment_location(info, info->sharename,
- &comment, &location)) {
- strlcpy(info->comment, comment, sizeof(info->comment));
- fstrcpy(info->location, location);
- TALLOC_FREE(comment);
- TALLOC_FREE(location);
- }
- }
- }
-#endif
-
- len += unpack_devicemode(&info->devmode,dbuf.dptr+len, dbuf.dsize-len);
-
- /*
- * Some client drivers freak out if there is a NULL devmode
- * (probably the driver is not checking before accessing
- * the devmode pointer) --jerry
- *
- * See comments in get_a_printer_2_default()
- */
-
- if (lp_default_devmode(snum) && !info->devmode) {
- DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
- printername));
- info->devmode = construct_nt_devicemode(printername);
- }
-
- slprintf( adevice, sizeof(adevice), "%s", info->printername );
- if (info->devmode) {
- fstrcpy(info->devmode->devicename, adevice);
- }
-
- if ( !(info->data = TALLOC_ZERO_P( info, NT_PRINTER_DATA )) ) {
- DEBUG(0,("unpack_values: talloc() failed!\n"));
- SAFE_FREE(dbuf.dptr);
- return WERR_NOMEM;
- }
- len += unpack_values( info->data, dbuf.dptr+len, dbuf.dsize-len );
-
- /* This will get the current RPC talloc context, but we should be
- passing this as a parameter... fixme... JRA ! */
-
- if (!nt_printing_getsec(info, sharename, &info->secdesc_buf)) {
- SAFE_FREE(dbuf.dptr);
- return WERR_NOMEM;
- }
-
- /* Fix for OS/2 drivers. */
-
- if (get_remote_arch() == RA_OS2) {
- map_to_os2_driver(info->drivername);
- }
-
- SAFE_FREE(dbuf.dptr);
-
- DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
- sharename, info->printername, info->drivername));
-
- return WERR_OK;
-}
-
-/****************************************************************************
- Debugging function, dump at level 6 the struct in the logs.
-****************************************************************************/
-static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
-{
- uint32 result;
- NT_PRINTER_INFO_LEVEL_2 *info2;
-
- DEBUG(106,("Dumping printer at level [%d]\n", level));
-
- switch (level) {
- case 2:
- {
- if (printer->info_2 == NULL)
- result=5;
- else
- {
- info2=printer->info_2;
-
- DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
- DEBUGADD(106,("priority:[%d]\n", info2->priority));
- DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
- DEBUGADD(106,("starttime:[%d]\n", info2->starttime));
- DEBUGADD(106,("untiltime:[%d]\n", info2->untiltime));
- DEBUGADD(106,("status:[%d]\n", info2->status));
- DEBUGADD(106,("cjobs:[%d]\n", info2->cjobs));
- DEBUGADD(106,("averageppm:[%d]\n", info2->averageppm));
- DEBUGADD(106,("changeid:[%d]\n", info2->changeid));
- DEBUGADD(106,("c_setprinter:[%d]\n", info2->c_setprinter));
- DEBUGADD(106,("setuptime:[%d]\n", info2->setuptime));
-
- DEBUGADD(106,("servername:[%s]\n", info2->servername));
- DEBUGADD(106,("printername:[%s]\n", info2->printername));
- DEBUGADD(106,("sharename:[%s]\n", info2->sharename));
- DEBUGADD(106,("portname:[%s]\n", info2->portname));
- DEBUGADD(106,("drivername:[%s]\n", info2->drivername));
- DEBUGADD(106,("comment:[%s]\n", info2->comment));
- DEBUGADD(106,("location:[%s]\n", info2->location));
- DEBUGADD(106,("sepfile:[%s]\n", info2->sepfile));
- DEBUGADD(106,("printprocessor:[%s]\n", info2->printprocessor));
- DEBUGADD(106,("datatype:[%s]\n", info2->datatype));
- DEBUGADD(106,("parameters:[%s]\n", info2->parameters));
- result=0;
- }
- break;
- }
- default:
- DEBUGADD(106,("dump_a_printer: Level %u not implemented\n", (unsigned int)level ));
- result=1;
- break;
- }
-
- return result;
-}
-
-/****************************************************************************
- Update the changeid time.
- This is SO NASTY as some drivers need this to change, others need it
- static. This value will change every second, and I must hope that this
- is enough..... DON'T CHANGE THIS CODE WITHOUT A TEST MATRIX THE SIZE OF
- UTAH ! JRA.
-****************************************************************************/
-
-static uint32 rev_changeid(void)
-{
- struct timeval tv;
-
- get_process_uptime(&tv);
-
-#if 1 /* JERRY */
- /* Return changeid as msec since spooler restart */
- return tv.tv_sec * 1000 + tv.tv_usec / 1000;
-#else
- /*
- * This setting seems to work well but is too untested
- * to replace the above calculation. Left in for experiementation
- * of the reader --jerry (Tue Mar 12 09:15:05 CST 2002)
- */
- return tv.tv_sec * 10 + tv.tv_usec / 100000;
-#endif
-}
-
-
-/*
- * The function below are the high level ones.
- * only those ones must be called from the spoolss code.
- * JFM.
- */
-
-/****************************************************************************
- Modify a printer. This is called from SETPRINTERDATA/DELETEPRINTERDATA.
-****************************************************************************/
-
-WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
-{
- WERROR result;
-
- dump_a_printer(printer, level);
-
- switch (level) {
- case 2:
- {
- /*
- * Update the changestamp. Emperical tests show that the
- * ChangeID is always updated,but c_setprinter is
- * global spooler variable (not per printer).
- */
-
- /* ChangeID **must** be increasing over the lifetime
- of client's spoolss service in order for the
- client's cache to show updates */
-
- printer->info_2->changeid = rev_changeid();
-
- /*
- * Because one day someone will ask:
- * NT->NT An admin connection to a remote
- * printer show changes imeediately in
- * the properities dialog
- *
- * A non-admin connection will only show the
- * changes after viewing the properites page
- * 2 times. Seems to be related to a
- * race condition in the client between the spooler
- * updating the local cache and the Explorer.exe GUI
- * actually displaying the properties.
- *
- * This is fixed in Win2k. admin/non-admin
- * connections both display changes immediately.
- *
- * 14/12/01 --jerry
- */
-
- result=update_a_printer_2(printer->info_2);
- break;
- }
- default:
- result=WERR_UNKNOWN_LEVEL;
- break;
- }
-
- return result;
-}
-
-/****************************************************************************
- Initialize printer devmode & data with previously saved driver init values.
-****************************************************************************/
-
-static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
-{
- int len = 0;
- char *key = NULL;
- TDB_DATA dbuf;
- NT_PRINTER_INFO_LEVEL_2 info;
-
-
- ZERO_STRUCT(info);
-
- /*
- * Delete any printer data 'values' already set. When called for driver
- * replace, there will generally be some, but during an add printer, there
- * should not be any (if there are delete them).
- */
-
- if ( info_ptr->data )
- delete_all_printer_data( info_ptr, "" );
-
- if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX,
- info_ptr->drivername) < 0) {
- return false;
- }
-
- dbuf = tdb_fetch_bystring(tdb_drivers, key);
- if (!dbuf.dptr) {
- /*
- * When changing to a driver that has no init info in the tdb, remove
- * the previous drivers init info and leave the new on blank.
- */
- free_nt_devicemode(&info_ptr->devmode);
- SAFE_FREE(key);
- return false;
- }
-
- SAFE_FREE(key);
- /*
- * Get the saved DEVMODE..
- */
-
- len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
-
- /*
- * The saved DEVMODE contains the devicename from the printer used during
- * the initialization save. Change it to reflect the new printer.
- */
-
- if ( info.devmode ) {
- ZERO_STRUCT(info.devmode->devicename);
- fstrcpy(info.devmode->devicename, info_ptr->printername);
- }
-
- /*
- * NT/2k does not change out the entire DeviceMode of a printer
- * when changing the driver. Only the driverextra, private, &
- * driverversion fields. --jerry (Thu Mar 14 08:58:43 CST 2002)
- *
- * Later examination revealed that Windows NT/2k does reset the
- * the printer's device mode, bit **only** when you change a
- * property of the device mode such as the page orientation.
- * --jerry
- */
-
-
- /* Bind the saved DEVMODE to the new the printer */
-
- free_nt_devicemode(&info_ptr->devmode);
- info_ptr->devmode = info.devmode;
-
- DEBUG(10,("set_driver_init_2: Set printer [%s] init %s DEVMODE for driver [%s]\n",
- info_ptr->printername, info_ptr->devmode?"VALID":"NULL", info_ptr->drivername));
-
- /* Add the printer data 'values' to the new printer */
-
- if ( !(info_ptr->data = TALLOC_ZERO_P( info_ptr, NT_PRINTER_DATA )) ) {
- DEBUG(0,("set_driver_init_2: talloc() failed!\n"));
- return False;
- }
-
- len += unpack_values( info_ptr->data, dbuf.dptr+len, dbuf.dsize-len );
-
- SAFE_FREE(dbuf.dptr);
-
- return true;
-}
-
-/****************************************************************************
- Initialize printer devmode & data with previously saved driver init values.
- When a printer is created using AddPrinter, the drivername bound to the
- printer is used to lookup previously saved driver initialization info, which
- is bound to the new printer.
-****************************************************************************/
-
-bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
-{
- bool result = False;
-
- switch (level) {
- case 2:
- result = set_driver_init_2(printer->info_2);
- break;
-
- default:
- DEBUG(0,("set_driver_init: Programmer's error! Unknown driver_init level [%d]\n",
- level));
- break;
- }
-
- return result;
-}
-
-/****************************************************************************
- Delete driver init data stored for a specified driver
-****************************************************************************/
-
-bool del_driver_init(const char *drivername)
-{
- char *key;
- bool ret;
-
- if (!drivername || !*drivername) {
- DEBUG(3,("del_driver_init: No drivername specified!\n"));
- return false;
- }
-
- if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX, drivername) < 0) {
- return false;
- }
-
- DEBUG(6,("del_driver_init: Removing driver init data for [%s]\n",
- drivername));
-
- ret = (tdb_delete_bystring(tdb_drivers, key) == 0);
- SAFE_FREE(key);
- return ret;
-}
-
-/****************************************************************************
- Pack up the DEVMODE and values for a printer into a 'driver init' entry
- in the tdb. Note: this is different from the driver entry and the printer
- entry. There should be a single driver init entry for each driver regardless
- of whether it was installed from NT or 2K. Technically, they should be
- different, but they work out to the same struct.
-****************************************************************************/
-
-static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
-{
- char *key = NULL;
- uint8 *buf;
- int buflen, len, ret;
- int retlen;
- TDB_DATA dbuf;
-
- buf = NULL;
- buflen = 0;
-
- again:
- len = 0;
- len += pack_devicemode(info->devmode, buf+len, buflen-len);
-
- retlen = pack_values( info->data, buf+len, buflen-len );
- if (retlen == -1) {
- ret = -1;
- goto done;
- }
- len += retlen;
-
- if (buflen < len) {
- buf = (uint8 *)SMB_REALLOC(buf, len);
- if (!buf) {
- DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
- ret = -1;
- goto done;
- }
- buflen = len;
- goto again;
- }
-
- SAFE_FREE(key);
- if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX, info->drivername) < 0) {
- ret = (uint32)-1;
- goto done;
- }
-
- dbuf.dptr = buf;
- dbuf.dsize = len;
-
- ret = tdb_store_bystring(tdb_drivers, key, dbuf, TDB_REPLACE);
-
-done:
- if (ret == -1)
- DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
-
- SAFE_FREE(buf);
-
- DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & values for driver [%s]\n",
- info->sharename, info->drivername));
-
- return ret;
-}
-
-/****************************************************************************
- Update (i.e. save) the driver init info (DEVMODE and values) for a printer
-****************************************************************************/
-
-static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
-{
- uint32 result;
-
- dump_a_printer(printer, level);
-
- switch (level) {
- case 2:
- result = update_driver_init_2(printer->info_2);
- break;
- default:
- result = 1;
- break;
- }
-
- return result;
-}
-
-/****************************************************************************
- Convert the printer data value, a REG_BINARY array, into an initialization
- DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
- got to keep the endians happy :).
-****************************************************************************/
-
-static bool convert_driver_init(TALLOC_CTX *mem_ctx, NT_DEVICEMODE *nt_devmode,
- const uint8_t *data, uint32_t data_len)
-{
- struct spoolss_DeviceMode devmode;
- enum ndr_err_code ndr_err;
- DATA_BLOB blob;
-
- ZERO_STRUCT(devmode);
-
- blob = data_blob_const(data, data_len);
-
- ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &devmode,
- (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- DEBUG(10,("convert_driver_init: error parsing spoolss_DeviceMode\n"));
- return false;
- }
-
- return convert_devicemode("", &devmode, &nt_devmode);
-}
-
-/****************************************************************************
- Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
-
- 1. Use the driver's config DLL to this UNC printername and:
- a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
- b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
- 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
-
- The last step triggers saving the "driver initialization" information for
- this printer into the tdb. Later, new printers that use this driver will
- have this initialization information bound to them. This simulates the
- driver initialization, as if it had run on the Samba server (as it would
- have done on NT).
-
- The Win32 client side code requirement sucks! But until we can run arbitrary
- Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
-
- It would have been easier to use SetPrinter because all the UNMARSHALLING of
- the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
- about it and you will realize why. JRR 010720
-****************************************************************************/
-
-static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, uint32 data_len )
-{
- WERROR status = WERR_OK;
- TALLOC_CTX *ctx = NULL;
- NT_DEVICEMODE *nt_devmode = NULL;
- NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
-
- /*
- * When the DEVMODE is already set on the printer, don't try to unpack it.
- */
- DEBUG(8,("save_driver_init_2: Enter...\n"));
-
- if ( !printer->info_2->devmode && data_len ) {
- /*
- * Set devmode on printer info, so entire printer initialization can be
- * saved to tdb.
- */
-
- if ((ctx = talloc_init("save_driver_init_2")) == NULL)
- return WERR_NOMEM;
-
- if ((nt_devmode = SMB_MALLOC_P(NT_DEVICEMODE)) == NULL) {
- status = WERR_NOMEM;
- goto done;
- }
-
- ZERO_STRUCTP(nt_devmode);
-
- /*
- * The DEVMODE is held in the 'data' component of the param in raw binary.
- * Convert it to to a devmode structure
- */
- if ( !convert_driver_init( ctx, nt_devmode, data, data_len )) {
- DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
- status = WERR_INVALID_PARAM;
- goto done;
- }
-
- printer->info_2->devmode = nt_devmode;
- }
-
- /*
- * Pack up and add (or update) the DEVMODE and any current printer data to
- * a 'driver init' element in the tdb
- *
- */
-
- if ( update_driver_init(printer, 2) != 0 ) {
- DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
- status = WERR_NOMEM;
- goto done;
- }
-
- /*
- * If driver initialization info was successfully saved, set the current
- * printer to match it. This allows initialization of the current printer
- * as well as the driver.
- */
- status = mod_a_printer(printer, 2);
- if (!W_ERROR_IS_OK(status)) {
- DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
- printer->info_2->printername));
- }
-
- done:
- talloc_destroy(ctx);
- free_nt_devicemode( &nt_devmode );
-
- printer->info_2->devmode = tmp_devmode;
-
- return status;
-}
-
-/****************************************************************************
- Update the driver init info (DEVMODE and specifics) for a printer
-****************************************************************************/
-
-WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *data, uint32 data_len)
-{
- WERROR status = WERR_OK;
-
- switch (level) {
- case 2:
- status = save_driver_init_2( printer, data, data_len );
- break;
- default:
- status = WERR_UNKNOWN_LEVEL;
- break;
- }
-
- return status;
-}
-
-/****************************************************************************
- Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
-
- Previously the code had a memory allocation problem because it always
- used the TALLOC_CTX from the Printer_entry*. This context lasts
- as a long as the original handle is open. So if the client made a lot
- of getprinter[data]() calls, the memory usage would climb. Now we use
- a short lived TALLOC_CTX for printer_info_2 objects returned. We
- still use the Printer_entry->ctx for maintaining the cache copy though
- since that object must live as long as the handle by definition.
- --jerry
-
-****************************************************************************/
-
-static WERROR get_a_printer_internal( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level,
- const char *sharename, bool get_loc_com)
-{
- WERROR result;
- fstring servername;
-
- DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
-
- if ( !(*pp_printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
- DEBUG(0,("get_a_printer: talloc() fail.\n"));
- return WERR_NOMEM;
- }
-
- switch (level) {
- case 2:
- if ( !((*pp_printer)->info_2 = TALLOC_ZERO_P(*pp_printer, NT_PRINTER_INFO_LEVEL_2)) ) {
- DEBUG(0,("get_a_printer: talloc() fail.\n"));
- TALLOC_FREE( *pp_printer );
- return WERR_NOMEM;
- }
-
- if ( print_hnd )
- fstrcpy( servername, print_hnd->servername );
- else {
- fstrcpy( servername, "%L" );
- standard_sub_basic( "", "", servername,
- sizeof(servername)-1 );
- }
-
- result = get_a_printer_2( (*pp_printer)->info_2,
- servername, sharename, get_loc_com);
-
- /* we have a new printer now. Save it with this handle */
-
- if ( !W_ERROR_IS_OK(result) ) {
- TALLOC_FREE( *pp_printer );
- DEBUG(10,("get_a_printer: [%s] level %u returning %s\n",
- sharename, (unsigned int)level, win_errstr(result)));
- return result;
- }
-
- dump_a_printer( *pp_printer, level);
-
- break;
-
- default:
- TALLOC_FREE( *pp_printer );
- return WERR_UNKNOWN_LEVEL;
- }
-
- return WERR_OK;
-}
-
-WERROR get_a_printer( Printer_entry *print_hnd,
- NT_PRINTER_INFO_LEVEL **pp_printer,
- uint32 level,
- const char *sharename)
-{
- return get_a_printer_internal(print_hnd, pp_printer, level,
- sharename, true);
-}
-
-WERROR get_a_printer_search( Printer_entry *print_hnd,
- NT_PRINTER_INFO_LEVEL **pp_printer,
- uint32 level,
- const char *sharename)
-{
- return get_a_printer_internal(print_hnd, pp_printer, level,
- sharename, false);
-}
-
-/****************************************************************************
- Deletes a NT_PRINTER_INFO_LEVEL struct.
-****************************************************************************/
-
-uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
-{
- NT_PRINTER_INFO_LEVEL *printer = *pp_printer;
-
- if ( !printer )
- return 0;
-
- switch (level) {
- case 2:
- if ( printer->info_2 )
- free_nt_printer_info_level_2(&printer->info_2);
- break;
-
- default:
- DEBUG(0,("free_a_printer: unknown level! [%d]\n", level ));
- return 1;
- }
-
- TALLOC_FREE(*pp_printer);
-
- return 0;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-uint32_t add_a_printer_driver(TALLOC_CTX *mem_ctx,
- struct spoolss_AddDriverInfoCtr *r,
- char **driver_name,
- uint32_t *version)
-{
- struct spoolss_DriverInfo8 info8;
-
- ZERO_STRUCT(info8);
-
- DEBUG(10,("adding a printer at level [%d]\n", r->level));
-
- switch (r->level) {
- case 3:
- info8.version = r->info.info3->version;
- info8.driver_name = r->info.info3->driver_name;
- info8.architecture = r->info.info3->architecture;
- info8.driver_path = r->info.info3->driver_path;
- info8.data_file = r->info.info3->data_file;
- info8.config_file = r->info.info3->config_file;
- info8.help_file = r->info.info3->help_file;
- info8.monitor_name = r->info.info3->monitor_name;
- info8.default_datatype = r->info.info3->default_datatype;
- if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) {
- info8.dependent_files = r->info.info3->dependent_files->string;
- }
- break;
- case 6:
- info8.version = r->info.info6->version;
- info8.driver_name = r->info.info6->driver_name;
- info8.architecture = r->info.info6->architecture;
- info8.driver_path = r->info.info6->driver_path;
- info8.data_file = r->info.info6->data_file;
- info8.config_file = r->info.info6->config_file;
- info8.help_file = r->info.info6->help_file;
- info8.monitor_name = r->info.info6->monitor_name;
- info8.default_datatype = r->info.info6->default_datatype;
- if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) {
- info8.dependent_files = r->info.info6->dependent_files->string;
- }
- info8.driver_date = r->info.info6->driver_date;
- info8.driver_version = r->info.info6->driver_version;
- info8.manufacturer_name = r->info.info6->manufacturer_name;
- info8.manufacturer_url = r->info.info6->manufacturer_url;
- info8.hardware_id = r->info.info6->hardware_id;
- info8.provider = r->info.info6->provider;
- break;
- case 8:
- info8.version = r->info.info8->version;
- info8.driver_name = r->info.info8->driver_name;
- info8.architecture = r->info.info8->architecture;
- info8.driver_path = r->info.info8->driver_path;
- info8.data_file = r->info.info8->data_file;
- info8.config_file = r->info.info8->config_file;
- info8.help_file = r->info.info8->help_file;
- info8.monitor_name = r->info.info8->monitor_name;
- info8.default_datatype = r->info.info8->default_datatype;
- if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) {
- info8.dependent_files = r->info.info8->dependent_files->string;
- }
- if (r->info.info8->previous_names && r->info.info8->previous_names->string) {
- info8.previous_names = r->info.info8->previous_names->string;
- }
- info8.driver_date = r->info.info8->driver_date;
- info8.driver_version = r->info.info8->driver_version;
- info8.manufacturer_name = r->info.info8->manufacturer_name;
- info8.manufacturer_url = r->info.info8->manufacturer_url;
- info8.hardware_id = r->info.info8->hardware_id;
- info8.provider = r->info.info8->provider;
- info8.print_processor = r->info.info8->print_processor;
- info8.vendor_setup = r->info.info8->vendor_setup;
- if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) {
- info8.color_profiles = r->info.info8->color_profiles->string;
- }
- info8.inf_path = r->info.info8->inf_path;
- info8.printer_driver_attributes = r->info.info8->printer_driver_attributes;
- if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) {
- info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string;
- }
- info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date;
- info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version;
- break;
- default:
- return -1;
- }
-
- *driver_name = talloc_strdup(mem_ctx, info8.driver_name);
- if (!*driver_name) {
- return -1;
- }
- *version = info8.version;
-
- return add_a_printer_driver_8(&info8);
-}
-
-/****************************************************************************
-****************************************************************************/
-
-WERROR get_a_printer_driver(TALLOC_CTX *mem_ctx,
- struct spoolss_DriverInfo8 **driver,
- const char *drivername, const char *architecture,
- uint32_t version)
-{
- WERROR result;
- struct spoolss_DriverInfo3 info3;
- struct spoolss_DriverInfo8 *info8;
-
- ZERO_STRUCT(info3);
-
- /* Sometime we just want any version of the driver */
-
- if (version == DRIVER_ANY_VERSION) {
- /* look for Win2k first and then for NT4 */
- result = get_a_printer_driver_3(mem_ctx,
- &info3,
- drivername,
- architecture, 3);
- if (!W_ERROR_IS_OK(result)) {
- result = get_a_printer_driver_3(mem_ctx,
- &info3,
- drivername,
- architecture, 2);
- }
- } else {
- result = get_a_printer_driver_3(mem_ctx,
- &info3,
- drivername,
- architecture,
- version);
- }
-
- if (!W_ERROR_IS_OK(result)) {
- return result;
- }
-
- info8 = talloc_zero(mem_ctx, struct spoolss_DriverInfo8);
- if (!info8) {
- return WERR_NOMEM;
- }
-
- info8->version = info3.version;
- info8->driver_name = info3.driver_name;
- info8->architecture = info3.architecture;
- info8->driver_path = info3.driver_path;
- info8->data_file = info3.data_file;
- info8->config_file = info3.config_file;
- info8->help_file = info3.help_file;
- info8->dependent_files = info3.dependent_files;
- info8->monitor_name = info3.monitor_name;
- info8->default_datatype = info3.default_datatype;
-
- *driver = info8;
-
- return WERR_OK;
-}
-
-/****************************************************************************
-****************************************************************************/
-
-uint32_t free_a_printer_driver(struct spoolss_DriverInfo8 *driver)
-{
- talloc_free(driver);
- return 0;
-}
-
-
-/****************************************************************************
- Determine whether or not a particular driver is currently assigned
- to a printer
-****************************************************************************/
-
-bool printer_driver_in_use(const struct spoolss_DriverInfo8 *r)
-{
- int snum;
- int n_services = lp_numservices();
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- bool in_use = False;
-
- if (!r) {
- return false;
- }
-
- DEBUG(10,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n"));
-
- /* loop through the printers.tdb and check for the drivername */
-
- for (snum=0; snum<n_services && !in_use; snum++) {
- if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
- continue;
-
- if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum))) )
- continue;
-
- if (strequal(r->driver_name, printer->info_2->drivername))
- in_use = True;
-
- free_a_printer( &printer, 2 );
- }
-
- DEBUG(10,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
-
- if ( in_use ) {
- struct spoolss_DriverInfo8 *d;
- WERROR werr;
-
- DEBUG(5,("printer_driver_in_use: driver \"%s\" is currently in use\n", r->driver_name));
-
- /* we can still remove the driver if there is one of
- "Windows NT x86" version 2 or 3 left */
-
- if (!strequal("Windows NT x86", r->architecture)) {
- werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", DRIVER_ANY_VERSION);
- }
- else {
- switch (r->version) {
- case 2:
- werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", 3);
- break;
- case 3:
- werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", 2);
- break;
- default:
- DEBUG(0,("printer_driver_in_use: ERROR! unknown driver version (%d)\n",
- r->version));
- werr = WERR_UNKNOWN_PRINTER_DRIVER;
- break;
- }
- }
-
- /* now check the error code */
-
- if ( W_ERROR_IS_OK(werr) ) {
- /* it's ok to remove the driver, we have other architctures left */
- in_use = False;
- free_a_printer_driver(d);
- }
- }
-
- /* report that the driver is not in use by default */
-
- return in_use;
-}
-
-
-/**********************************************************************
- Check to see if a ogiven file is in use by *info
- *********************************************************************/
-
-static bool drv_file_in_use(const char *file, const struct spoolss_DriverInfo8 *info)
-{
- int i = 0;
-
- if ( !info )
- return False;
-
- /* mz: skip files that are in the list but already deleted */
- if (!file || !file[0]) {
- return false;
- }
-
- if (strequal(file, info->driver_path))
- return True;
-
- if (strequal(file, info->data_file))
- return True;
-
- if (strequal(file, info->config_file))
- return True;
-
- if (strequal(file, info->help_file))
- return True;
-
- /* see of there are any dependent files to examine */
-
- if (!info->dependent_files)
- return False;
-
- while (info->dependent_files[i] && *info->dependent_files[i]) {
- if (strequal(file, info->dependent_files[i]))
- return True;
- i++;
- }
-
- return False;
-
-}
-
-/**********************************************************************
- Utility function to remove the dependent file pointed to by the
- input parameter from the list
- *********************************************************************/
-
-static void trim_dependent_file(TALLOC_CTX *mem_ctx, const char **files, int idx)
-{
-
- /* bump everything down a slot */
-
- while (files && files[idx+1]) {
- files[idx] = talloc_strdup(mem_ctx, files[idx+1]);
- idx++;
- }
-
- files[idx] = NULL;
-
- return;
-}
-
-/**********************************************************************
- Check if any of the files used by src are also used by drv
- *********************************************************************/
-
-static bool trim_overlap_drv_files(TALLOC_CTX *mem_ctx,
- struct spoolss_DriverInfo8 *src,
- const struct spoolss_DriverInfo8 *drv)
-{
- bool in_use = False;
- int i = 0;
-
- if ( !src || !drv )
- return False;
-
- /* check each file. Remove it from the src structure if it overlaps */
-
- if (drv_file_in_use(src->driver_path, drv)) {
- in_use = True;
- DEBUG(10,("Removing driverfile [%s] from list\n", src->driver_path));
- src->driver_path = talloc_strdup(mem_ctx, "");
- if (!src->driver_path) { return false; }
- }
-
- if (drv_file_in_use(src->data_file, drv)) {
- in_use = True;
- DEBUG(10,("Removing datafile [%s] from list\n", src->data_file));
- src->data_file = talloc_strdup(mem_ctx, "");
- if (!src->data_file) { return false; }
- }
-
- if (drv_file_in_use(src->config_file, drv)) {
- in_use = True;
- DEBUG(10,("Removing configfile [%s] from list\n", src->config_file));
- src->config_file = talloc_strdup(mem_ctx, "");
- if (!src->config_file) { return false; }
- }
-
- if (drv_file_in_use(src->help_file, drv)) {
- in_use = True;
- DEBUG(10,("Removing helpfile [%s] from list\n", src->help_file));
- src->help_file = talloc_strdup(mem_ctx, "");
- if (!src->help_file) { return false; }
- }
-
- /* are there any dependentfiles to examine? */
-
- if (!src->dependent_files)
- return in_use;
-
- while (src->dependent_files[i] && *src->dependent_files[i]) {
- if (drv_file_in_use(src->dependent_files[i], drv)) {
- in_use = True;
- DEBUG(10,("Removing [%s] from dependent file list\n", src->dependent_files[i]));
- trim_dependent_file(mem_ctx, src->dependent_files, i);
- } else
- i++;
- }
-
- return in_use;
-}
-
-/****************************************************************************
- Determine whether or not a particular driver files are currently being
- used by any other driver.
-
- Return value is True if any files were in use by other drivers
- and False otherwise.
-
- Upon return, *info has been modified to only contain the driver files
- which are not in use
-
- Fix from mz:
-
- This needs to check all drivers to ensure that all files in use
- have been removed from *info, not just the ones in the first
- match.
-****************************************************************************/
-
-bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx,
- struct spoolss_DriverInfo8 *info)
-{
- int i;
- int ndrivers;
- uint32 version;
- fstring *list = NULL;
- struct spoolss_DriverInfo8 *driver;
- bool in_use = false;
-
- if ( !info )
- return False;
-
- version = info->version;
-
- /* loop over all driver versions */
-
- DEBUG(5,("printer_driver_files_in_use: Beginning search through ntdrivers.tdb...\n"));
-
- /* get the list of drivers */
-
- list = NULL;
- ndrivers = get_ntdrivers(&list, info->architecture, version);
-
- DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
- ndrivers, info->architecture, version));
-
- /* check each driver for overlap in files */
-
- for (i=0; i<ndrivers; i++) {
- DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
-
- driver = NULL;
-
- if (!W_ERROR_IS_OK(get_a_printer_driver(talloc_tos(), &driver, list[i], info->architecture, version))) {
- SAFE_FREE(list);
- return True;
- }
-
- /* check if d2 uses any files from d1 */
- /* only if this is a different driver than the one being deleted */
-
- if (!strequal(info->driver_name, driver->driver_name)) {
- if (trim_overlap_drv_files(mem_ctx, info, driver)) {
- /* mz: Do not instantly return -
- * we need to ensure this file isn't
- * also in use by other drivers. */
- in_use = true;
- }
- }
-
- free_a_printer_driver(driver);
- }
-
- SAFE_FREE(list);
-
- DEBUG(5,("printer_driver_files_in_use: Completed search through ntdrivers.tdb...\n"));
-
- return in_use;
-}
-
-static NTSTATUS driver_unlink_internals(connection_struct *conn,
- const char *name)
-{
- struct smb_filename *smb_fname = NULL;
- NTSTATUS status;
-
- status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
- &smb_fname);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
-
- status = unlink_internals(conn, NULL, 0, smb_fname, false);
-
- TALLOC_FREE(smb_fname);
- return status;
-}
-
-/****************************************************************************
- Actually delete the driver files. Make sure that
- printer_driver_files_in_use() return False before calling
- this.
-****************************************************************************/
-
-static bool delete_driver_files(struct pipes_struct *rpc_pipe,
- const struct spoolss_DriverInfo8 *r)
-{
- int i = 0;
- char *s;
- const char *file;
- connection_struct *conn;
- NTSTATUS nt_status;
- char *oldcwd;
- fstring printdollar;
- int printdollar_snum;
- bool ret = false;
-
- if (!r) {
- return false;
- }
-
- DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n",
- r->driver_name, r->version));
-
- fstrcpy(printdollar, "print$");
-
- printdollar_snum = find_service(printdollar);
- if (printdollar_snum == -1) {
- return false;
- }
-
- nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
- lp_pathname(printdollar_snum),
- rpc_pipe->server_info, &oldcwd);
- if (!NT_STATUS_IS_OK(nt_status)) {
- DEBUG(0,("delete_driver_files: create_conn_struct "
- "returned %s\n", nt_errstr(nt_status)));
- return false;
- }
-
- if ( !CAN_WRITE(conn) ) {
- DEBUG(3,("delete_driver_files: Cannot delete print driver when [print$] is read-only\n"));
- goto fail;
- }
-
- /* now delete the files; must strip the '\print$' string from
- fron of path */
-
- if (r->driver_path && r->driver_path[0]) {
- if ((s = strchr(&r->driver_path[1], '\\')) != NULL) {
- file = s;
- DEBUG(10,("deleting driverfile [%s]\n", s));
- driver_unlink_internals(conn, file);
- }
- }
-
- if (r->config_file && r->config_file[0]) {
- if ((s = strchr(&r->config_file[1], '\\')) != NULL) {
- file = s;
- DEBUG(10,("deleting configfile [%s]\n", s));
- driver_unlink_internals(conn, file);
- }
- }
-
- if (r->data_file && r->data_file[0]) {
- if ((s = strchr(&r->data_file[1], '\\')) != NULL) {
- file = s;
- DEBUG(10,("deleting datafile [%s]\n", s));
- driver_unlink_internals(conn, file);
- }
- }
-
- if (r->help_file && r->help_file[0]) {
- if ((s = strchr(&r->help_file[1], '\\')) != NULL) {
- file = s;
- DEBUG(10,("deleting helpfile [%s]\n", s));
- driver_unlink_internals(conn, file);
- }
- }
-
- /* check if we are done removing files */
-
- if (r->dependent_files) {
- while (r->dependent_files[i] && r->dependent_files[i][0]) {
- char *p;
-
- /* bypass the "\print$" portion of the path */
-
- if ((p = strchr(r->dependent_files[i]+1, '\\')) != NULL) {
- file = p;
- DEBUG(10,("deleting dependent file [%s]\n", file));
- driver_unlink_internals(conn, file);
- }
-
- i++;
- }
- }
-
- goto done;
- fail:
- ret = false;
- done:
- if (conn != NULL) {
- vfs_ChDir(conn, oldcwd);
- conn_free(conn);
- }
- return ret;
-}
-
-/****************************************************************************
- Remove a printer driver from the TDB. This assumes that the the driver was
- previously looked up.
- ***************************************************************************/
-
-WERROR delete_printer_driver(struct pipes_struct *rpc_pipe,
- const struct spoolss_DriverInfo8 *r,
- uint32 version, bool delete_files )
-{
- char *key = NULL;
- const char *arch;
- TDB_DATA dbuf;
-
- /* delete the tdb data first */
-
- arch = get_short_archi(r->architecture);
- if (!arch) {
- return WERR_UNKNOWN_PRINTER_DRIVER;
- }
- if (asprintf(&key, "%s%s/%d/%s", DRIVERS_PREFIX,
- arch, version, r->driver_name) < 0) {
- return WERR_NOMEM;
- }
-
- DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n",
- key, delete_files ? "TRUE" : "FALSE" ));
-
- /* check if the driver actually exists for this environment */
-
- dbuf = tdb_fetch_bystring( tdb_drivers, key );
- if ( !dbuf.dptr ) {
- DEBUG(8,("delete_printer_driver: Driver unknown [%s]\n", key));
- SAFE_FREE(key);
- return WERR_UNKNOWN_PRINTER_DRIVER;
- }
-
- SAFE_FREE( dbuf.dptr );
-
- /* ok... the driver exists so the delete should return success */
-
- if (tdb_delete_bystring(tdb_drivers, key) == -1) {
- DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
- SAFE_FREE(key);
- return WERR_ACCESS_DENIED;
- }
-
- /*
- * now delete any associated files if delete_files == True
- * even if this part failes, we return succes because the
- * driver doesn not exist any more
- */
-
- if ( delete_files )
- delete_driver_files(rpc_pipe, r);
-
- DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key));
- SAFE_FREE(key);
-
- return WERR_OK;
-}
-
-/****************************************************************************
- Store a security desc for a printer.
-****************************************************************************/
-
-WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
-{
- SEC_DESC_BUF *new_secdesc_ctr = NULL;
- SEC_DESC_BUF *old_secdesc_ctr = NULL;
- TALLOC_CTX *mem_ctx = NULL;
- TDB_DATA kbuf;
- TDB_DATA dbuf;
- DATA_BLOB blob;
- WERROR status;
- NTSTATUS nt_status;
-
- mem_ctx = talloc_init("nt_printing_setsec");
- if (mem_ctx == NULL)
- return WERR_NOMEM;
-
- /* The old owner and group sids of the security descriptor are not
- present when new ACEs are added or removed by changing printer
- permissions through NT. If they are NULL in the new security
- descriptor then copy them over from the old one. */
-
- if (!secdesc_ctr->sd->owner_sid || !secdesc_ctr->sd->group_sid) {
- DOM_SID *owner_sid, *group_sid;
- SEC_ACL *dacl, *sacl;
- SEC_DESC *psd = NULL;
- size_t size;
-
- if (!nt_printing_getsec(mem_ctx, sharename, &old_secdesc_ctr)) {
- status = WERR_NOMEM;
- goto out;
- }
-
- /* Pick out correct owner and group sids */
-
- owner_sid = secdesc_ctr->sd->owner_sid ?
- secdesc_ctr->sd->owner_sid :
- old_secdesc_ctr->sd->owner_sid;
-
- group_sid = secdesc_ctr->sd->group_sid ?
- secdesc_ctr->sd->group_sid :
- old_secdesc_ctr->sd->group_sid;
-
- dacl = secdesc_ctr->sd->dacl ?
- secdesc_ctr->sd->dacl :
- old_secdesc_ctr->sd->dacl;
-
- sacl = secdesc_ctr->sd->sacl ?
- secdesc_ctr->sd->sacl :
- old_secdesc_ctr->sd->sacl;
-
- /* Make a deep copy of the security descriptor */
-
- psd = make_sec_desc(mem_ctx, secdesc_ctr->sd->revision, secdesc_ctr->sd->type,
- owner_sid, group_sid,
- sacl,
- dacl,
- &size);
-
- if (!psd) {
- status = WERR_NOMEM;
- goto out;
- }
-
- new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);
- }
-
- if (!new_secdesc_ctr) {
- new_secdesc_ctr = secdesc_ctr;
- }
-
- /* Store the security descriptor in a tdb */
-
- nt_status = marshall_sec_desc_buf(mem_ctx, new_secdesc_ctr,
- &blob.data, &blob.length);
- if (!NT_STATUS_IS_OK(nt_status)) {
- status = ntstatus_to_werror(nt_status);
- goto out;
- }
-
- kbuf = make_printers_secdesc_tdbkey(mem_ctx, sharename );
-
- dbuf.dptr = (unsigned char *)blob.data;
- dbuf.dsize = blob.length;
-
- if (tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE)==0) {
- status = WERR_OK;
- } else {
- DEBUG(1,("Failed to store secdesc for %s\n", sharename));
- status = WERR_BADFUNC;
- }
-
- /* Free malloc'ed memory */
- talloc_free(blob.data);
-
- out:
-
- if (mem_ctx)
- talloc_destroy(mem_ctx);
- return status;
-}
-
-/****************************************************************************
- Construct a default security descriptor buffer for a printer.
-****************************************************************************/
-
-static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
-{
- SEC_ACE ace[5]; /* max number of ace entries */
- int i = 0;
- uint32_t sa;
- SEC_ACL *psa = NULL;
- SEC_DESC_BUF *sdb = NULL;
- SEC_DESC *psd = NULL;
- DOM_SID adm_sid;
- size_t sd_size;
-
- /* Create an ACE where Everyone is allowed to print */
-
- sa = PRINTER_ACE_PRINT;
- init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
- sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-
- /* Add the domain admins group if we are a DC */
-
- if ( IS_DC ) {
- DOM_SID domadmins_sid;
-
- sid_compose(&domadmins_sid, get_global_sam_sid(),
- DOMAIN_GROUP_RID_ADMINS);
-
- sa = PRINTER_ACE_FULL_CONTROL;
- init_sec_ace(&ace[i++], &domadmins_sid,
- SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
- SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
- init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
- sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
- }
- else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
- sid_append_rid(&adm_sid, DOMAIN_USER_RID_ADMIN);
-
- sa = PRINTER_ACE_FULL_CONTROL;
- init_sec_ace(&ace[i++], &adm_sid,
- SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
- SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
- init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
- sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
- }
-
- /* add BUILTIN\Administrators as FULL CONTROL */
-
- sa = PRINTER_ACE_FULL_CONTROL;
- init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
- SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
- SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
- init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
- SEC_ACE_TYPE_ACCESS_ALLOWED,
- sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-
- /* Make the security descriptor owned by the BUILTIN\Administrators */
-
- /* The ACL revision number in rpc_secdesc.h differs from the one
- created by NT when setting ACE entries in printer
- descriptors. NT4 complains about the property being edited by a
- NT5 machine. */
-
- if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
- psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
- &global_sid_Builtin_Administrators,
- &global_sid_Builtin_Administrators,
- NULL, psa, &sd_size);
- }
-
- if (!psd) {
- DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
- return NULL;
- }
-
- sdb = make_sec_desc_buf(ctx, sd_size, psd);
-
- DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
- (unsigned int)sd_size));
-
- return sdb;
-}
-
-/****************************************************************************
- Get a security desc for a printer.
-****************************************************************************/
-
-bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **secdesc_ctr)
-{
- TDB_DATA kbuf;
- TDB_DATA dbuf;
- DATA_BLOB blob;
- char *temp;
- NTSTATUS status;
-
- if (strlen(sharename) > 2 && (temp = strchr(sharename + 2, '\\'))) {
- sharename = temp + 1;
- }
-
- /* Fetch security descriptor from tdb */
-
- kbuf = make_printers_secdesc_tdbkey(ctx, sharename);
-
- dbuf = tdb_fetch(tdb_printers, kbuf);
- if (dbuf.dptr) {
-
- status = unmarshall_sec_desc_buf(ctx, dbuf.dptr, dbuf.dsize,
- secdesc_ctr);
- SAFE_FREE(dbuf.dptr);
-
- if (NT_STATUS_IS_OK(status)) {
- return true;
- }
- }
-
- *secdesc_ctr = construct_default_printer_sdb(ctx);
- if (!*secdesc_ctr) {
- return false;
- }
-
- status = marshall_sec_desc_buf(ctx, *secdesc_ctr,
- &blob.data, &blob.length);
- if (NT_STATUS_IS_OK(status)) {
- dbuf.dptr = (unsigned char *)blob.data;
- dbuf.dsize = blob.length;
- tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE);
- talloc_free(blob.data);
- }
-
- /* If security descriptor is owned by S-1-1-0 and winbindd is up,
- this security descriptor has been created when winbindd was
- down. Take ownership of security descriptor. */
-
- if (sid_equal((*secdesc_ctr)->sd->owner_sid, &global_sid_World)) {
- DOM_SID owner_sid;
-
- /* Change sd owner to workgroup administrator */
-
- if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
- SEC_DESC_BUF *new_secdesc_ctr = NULL;
- SEC_DESC *psd = NULL;
- size_t size;
-
- /* Create new sd */
-
- sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
-
- psd = make_sec_desc(ctx, (*secdesc_ctr)->sd->revision, (*secdesc_ctr)->sd->type,
- &owner_sid,
- (*secdesc_ctr)->sd->group_sid,
- (*secdesc_ctr)->sd->sacl,
- (*secdesc_ctr)->sd->dacl,
- &size);
-
- if (!psd) {
- return False;
- }
-
- new_secdesc_ctr = make_sec_desc_buf(ctx, size, psd);
- if (!new_secdesc_ctr) {
- return False;
- }
-
- /* Swap with other one */
-
- *secdesc_ctr = new_secdesc_ctr;
-
- /* Set it */
-
- nt_printing_setsec(sharename, *secdesc_ctr);
- }
- }
-
- if (DEBUGLEVEL >= 10) {
- SEC_ACL *the_acl = (*secdesc_ctr)->sd->dacl;
- int i;
-
- DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
- sharename, the_acl->num_aces));
-
- for (i = 0; i < the_acl->num_aces; i++) {
- DEBUG(10, ("%s %d %d 0x%08x\n",
- sid_string_dbg(&the_acl->aces[i].trustee),
- the_acl->aces[i].type, the_acl->aces[i].flags,
- the_acl->aces[i].access_mask));
- }
- }
-
- return True;
-}
-
-/* error code:
- 0: everything OK
- 1: level not implemented
- 2: file doesn't exist
- 3: can't allocate memory
- 4: can't free memory
- 5: non existant struct
-*/
-
-/*
- A printer and a printer driver are 2 different things.
- NT manages them separatelly, Samba does the same.
- Why ? Simply because it's easier and it makes sense !
-
- Now explanation: You have 3 printers behind your samba server,
- 2 of them are the same make and model (laser A and B). But laser B
- has an 3000 sheet feeder and laser A doesn't such an option.
- Your third printer is an old dot-matrix model for the accounting :-).
-
- If the /usr/local/samba/lib directory (default dir), you will have
- 5 files to describe all of this.
-
- 3 files for the printers (1 by printer):
- NTprinter_laser A
- NTprinter_laser B
- NTprinter_accounting
- 2 files for the drivers (1 for the laser and 1 for the dot matrix)
- NTdriver_printer model X
- NTdriver_printer model Y
-
-jfm: I should use this comment for the text file to explain
- same thing for the forms BTW.
- Je devrais mettre mes commentaires en francais, ca serait mieux :-)
-
-*/
-
-/* Convert generic access rights to printer object specific access rights.
- It turns out that NT4 security descriptors use generic access rights and
- NT5 the object specific ones. */
-
-void map_printer_permissions(SEC_DESC *sd)
-{
- int i;
-
- for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
- se_map_generic(&sd->dacl->aces[i].access_mask,
- &printer_generic_mapping);
- }
-}
-
-void map_job_permissions(SEC_DESC *sd)
-{
- int i;
-
- for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
- se_map_generic(&sd->dacl->aces[i].access_mask,
- &job_generic_mapping);
- }
-}
-
-
-/****************************************************************************
- Check a user has permissions to perform the given operation. We use the
- permission constants defined in include/rpc_spoolss.h to check the various
- actions we perform when checking printer access.
-
- PRINTER_ACCESS_ADMINISTER:
- print_queue_pause, print_queue_resume, update_printer_sec,
- update_printer, spoolss_addprinterex_level_2,
- _spoolss_setprinterdata
-
- PRINTER_ACCESS_USE:
- print_job_start
-
- JOB_ACCESS_ADMINISTER:
- print_job_delete, print_job_pause, print_job_resume,
- print_queue_purge
-
- Try access control in the following order (for performance reasons):
- 1) root and SE_PRINT_OPERATOR can do anything (easy check)
- 2) check security descriptor (bit comparisons in memory)
- 3) "printer admins" (may result in numerous calls to winbind)
-
- ****************************************************************************/
-bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
- int access_type)
-{
- SEC_DESC_BUF *secdesc = NULL;
- uint32 access_granted;
- NTSTATUS status;
- const char *pname;
- TALLOC_CTX *mem_ctx = NULL;
- SE_PRIV se_printop = SE_PRINT_OPERATOR;
-
- /* If user is NULL then use the current_user structure */
-
- /* Always allow root or SE_PRINT_OPERATROR to do anything */
-
- if (server_info->utok.uid == sec_initial_uid()
- || user_has_privileges(server_info->ptok, &se_printop ) ) {
- return True;
- }
-
- /* Get printer name */
-
- pname = PRINTERNAME(snum);
-
- if (!pname || !*pname) {
- errno = EACCES;
- return False;
- }
-
- /* Get printer security descriptor */
-
- if(!(mem_ctx = talloc_init("print_access_check"))) {
- errno = ENOMEM;
- return False;
- }
-
- if (!nt_printing_getsec(mem_ctx, pname, &secdesc)) {
- talloc_destroy(mem_ctx);
- errno = ENOMEM;
- return False;
- }
-
- if (access_type == JOB_ACCESS_ADMINISTER) {
- SEC_DESC_BUF *parent_secdesc = secdesc;
-
- /* Create a child security descriptor to check permissions
- against. This is because print jobs are child objects
- objects of a printer. */
-
- status = se_create_child_secdesc_buf(mem_ctx, &secdesc, parent_secdesc->sd, False);
-
- if (!NT_STATUS_IS_OK(status)) {
- talloc_destroy(mem_ctx);
- errno = map_errno_from_nt_status(status);
- return False;
- }
-
- map_job_permissions(secdesc->sd);
- } else {
- map_printer_permissions(secdesc->sd);
- }
-
- /* Check access */
- status = se_access_check(secdesc->sd, server_info->ptok, access_type,
- &access_granted);
-
- DEBUG(4, ("access check was %s\n", NT_STATUS_IS_OK(status) ? "SUCCESS" : "FAILURE"));
-
- /* see if we need to try the printer admin list */
-
- if (!NT_STATUS_IS_OK(status) &&
- (token_contains_name_in_list(uidtoname(server_info->utok.uid),
- NULL, NULL, server_info->ptok,
- lp_printer_admin(snum)))) {
- talloc_destroy(mem_ctx);
- return True;
- }
-
- talloc_destroy(mem_ctx);
-
- if (!NT_STATUS_IS_OK(status)) {
- errno = EACCES;
- }
-
- return NT_STATUS_IS_OK(status);
-}
-
-/****************************************************************************
- Check the time parameters allow a print operation.
-*****************************************************************************/
-
-bool print_time_access_check(const char *servicename)
-{
- NT_PRINTER_INFO_LEVEL *printer = NULL;
- bool ok = False;
- time_t now = time(NULL);
- struct tm *t;
- uint32 mins;
-
- if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
- return False;
-
- if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)
- ok = True;
-
- t = gmtime(&now);
- mins = (uint32)t->tm_hour*60 + (uint32)t->tm_min;
-
- if (mins >= printer->info_2->starttime && mins <= printer->info_2->untiltime)
- ok = True;
-
- free_a_printer(&printer, 2);
-
- if (!ok)
- errno = EACCES;
-
- return ok;
-}
-
-/****************************************************************************
- Fill in the servername sent in the _spoolss_open_printer_ex() call
-****************************************************************************/
-
-char* get_server_name( Printer_entry *printer )
-{
- return printer->servername;
-}
-
-
+++ /dev/null
-/*
- Unix SMB/CIFS implementation.
- printcap parsing
- Copyright (C) Karl Auer 1993-1998
-
- Re-working by Martin Kiff, 1994
-
- Re-written again by Andrew Tridgell
-
- Modified for SVID support by Norm Jacobs, 1997
-
- Modified for CUPS support by Michael Sweet, 1999
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * This module contains code to parse and cache printcap data, possibly
- * in concert with the CUPS/SYSV/AIX-specific code found elsewhere.
- *
- * The way this module looks at the printcap file is very simplistic.
- * Only the local printcap file is inspected (no searching of NIS
- * databases etc).
- *
- * There are assumed to be one or more printer names per record, held
- * as a set of sub-fields separated by vertical bar symbols ('|') in the
- * first field of the record. The field separator is assumed to be a colon
- * ':' and the record separator a newline.
- *
- * Lines ending with a backspace '\' are assumed to flag that the following
- * line is a continuation line so that a set of lines can be read as one
- * printcap entry.
- *
- * A line stating with a hash '#' is assumed to be a comment and is ignored
- * Comments are discarded before the record is strung together from the
- * set of continuation lines.
- *
- * Opening a pipe for "lpc status" and reading that would probably
- * be pretty effective. Code to do this already exists in the freely
- * distributable PCNFS server code.
- *
- * Modified to call SVID/XPG4 support if printcap name is set to "lpstat"
- * in smb.conf under Solaris.
- *
- * Modified to call CUPS support if printcap name is set to "cups"
- * in smb.conf.
- *
- * Modified to call iPrint support if printcap name is set to "iprint"
- * in smb.conf.
- */
-
-#include "includes.h"
-
-
-struct pcap_cache {
- char *name;
- char *comment;
- struct pcap_cache *next;
-};
-
-/* The systemwide printcap cache. */
-static struct pcap_cache *pcap_cache = NULL;
-
-bool pcap_cache_add_specific(struct pcap_cache **ppcache, const char *name, const char *comment)
-{
- struct pcap_cache *p;
-
- if (name == NULL || ((p = SMB_MALLOC_P(struct pcap_cache)) == NULL))
- return false;
-
- p->name = SMB_STRDUP(name);
- p->comment = (comment && *comment) ? SMB_STRDUP(comment) : NULL;
-
- DEBUG(11,("pcap_cache_add_specific: Adding name %s info %s\n",
- p->name, p->comment ? p->comment : ""));
-
- p->next = *ppcache;
- *ppcache = p;
-
- return true;
-}
-
-void pcap_cache_destroy_specific(struct pcap_cache **pp_cache)
-{
- struct pcap_cache *p, *next;
-
- for (p = *pp_cache; p != NULL; p = next) {
- next = p->next;
-
- SAFE_FREE(p->name);
- SAFE_FREE(p->comment);
- SAFE_FREE(p);
- }
- *pp_cache = NULL;
-}
-
-bool pcap_cache_add(const char *name, const char *comment)
-{
- return pcap_cache_add_specific(&pcap_cache, name, comment);
-}
-
-bool pcap_cache_loaded(void)
-{
- return (pcap_cache != NULL);
-}
-
-void pcap_cache_replace(const struct pcap_cache *pcache)
-{
- const struct pcap_cache *p;
-
- pcap_cache_destroy_specific(&pcap_cache);
- for (p = pcache; p; p = p->next) {
- pcap_cache_add(p->name, p->comment);
- }
-}
-
-void pcap_cache_reload(void)
-{
- const char *pcap_name = lp_printcapname();
- bool pcap_reloaded = False;
- struct pcap_cache *tmp_cache = NULL;
- XFILE *pcap_file;
- char *pcap_line;
-
- DEBUG(3, ("reloading printcap cache\n"));
-
- /* only go looking if no printcap name supplied */
- if (pcap_name == NULL || *pcap_name == 0) {
- DEBUG(0, ("No printcap file name configured!\n"));
- return;
- }
-
- tmp_cache = pcap_cache;
- pcap_cache = NULL;
-
-#ifdef HAVE_CUPS
- if (strequal(pcap_name, "cups")) {
- pcap_reloaded = cups_cache_reload();
- goto done;
- }
-#endif
-
-#ifdef HAVE_IPRINT
- if (strequal(pcap_name, "iprint")) {
- pcap_reloaded = iprint_cache_reload();
- goto done;
- }
-#endif
-
-#if defined(SYSV) || defined(HPUX)
- if (strequal(pcap_name, "lpstat")) {
- pcap_reloaded = sysv_cache_reload();
- goto done;
- }
-#endif
-
-#ifdef AIX
- if (strstr_m(pcap_name, "/qconfig") != NULL) {
- pcap_reloaded = aix_cache_reload();
- goto done;
- }
-#endif
-
- /* handle standard printcap - moved from pcap_printer_fn() */
-
- if ((pcap_file = x_fopen(pcap_name, O_RDONLY, 0)) == NULL) {
- DEBUG(0, ("Unable to open printcap file %s for read!\n", pcap_name));
- goto done;
- }
-
- for (; (pcap_line = fgets_slash(NULL, 1024, pcap_file)) != NULL; free(pcap_line)) {
- char name[MAXPRINTERLEN+1];
- char comment[62];
- char *p, *q;
-
- if (*pcap_line == '#' || *pcap_line == 0)
- continue;
-
- /* now we have a real printer line - cut at the first : */
- if ((p = strchr_m(pcap_line, ':')) != NULL)
- *p = 0;
-
- /*
- * now find the most likely printer name and comment
- * this is pure guesswork, but it's better than nothing
- */
- for (*name = *comment = 0, p = pcap_line; p != NULL; p = q) {
- bool has_punctuation;
-
- if ((q = strchr_m(p, '|')) != NULL)
- *q++ = 0;
-
- has_punctuation = (strchr_m(p, ' ') ||
- strchr_m(p, '\t') ||
- strchr_m(p, '(') ||
- strchr_m(p, ')'));
-
- if (strlen(p) > strlen(comment) && has_punctuation) {
- strlcpy(comment, p, sizeof(comment));
- continue;
- }
-
- if (strlen(p) <= MAXPRINTERLEN &&
- strlen(p) > strlen(name) && !has_punctuation) {
- if (!*comment) {
- strlcpy(comment, name, sizeof(comment));
- }
- strlcpy(name, p, sizeof(name));
- continue;
- }
-
- if (!strchr_m(comment, ' ') &&
- strlen(p) > strlen(comment)) {
- strlcpy(comment, p, sizeof(comment));
- continue;
- }
- }
-
- comment[60] = 0;
- name[MAXPRINTERLEN] = 0;
-
- if (*name && !pcap_cache_add(name, comment)) {
- x_fclose(pcap_file);
- goto done;
- }
- }
-
- x_fclose(pcap_file);
- pcap_reloaded = True;
-
-done:
- DEBUG(3, ("reload status: %s\n", (pcap_reloaded) ? "ok" : "error"));
-
- if (pcap_reloaded)
- pcap_cache_destroy_specific(&tmp_cache);
- else {
- pcap_cache_destroy_specific(&pcap_cache);
- pcap_cache = tmp_cache;
- }
-
- return;
-}
-
-
-bool pcap_printername_ok(const char *printername)
-{
- struct pcap_cache *p;
-
- for (p = pcap_cache; p != NULL; p = p->next)
- if (strequal(p->name, printername))
- return True;
-
- return False;
-}
-
-/***************************************************************************
-run a function on each printer name in the printcap file.
-***************************************************************************/
-
-void pcap_printer_fn_specific(const struct pcap_cache *pc,
- void (*fn)(const char *, const char *, void *),
- void *pdata)
-{
- const struct pcap_cache *p;
-
- for (p = pc; p != NULL; p = p->next)
- fn(p->name, p->comment, pdata);
-
- return;
-}
-
-void pcap_printer_fn(void (*fn)(const char *, const char *, void *), void *pdata)
-{
- pcap_printer_fn_specific(pcap_cache, fn, pdata);
-}
+++ /dev/null
-/*
- AIX-specific printcap loading
- Copyright (C) Jean-Pierre.Boulard@univ-rennes1.fr 1996
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-/*
- * This module implements AIX-specific printcap loading. Most of the code
- * here was originally provided by Jean-Pierre.Boulard@univ-rennes1.fr in
- * the Samba 1.9.14 release, and was formerly contained in pcap.c. It has
- * been moved here and condensed as part of a larger effort to clean up and
- * simplify the printcap code. -- Rob Foehl, 2004/12/06
- */
-
-#include "includes.h"
-
-#ifdef AIX
-bool aix_cache_reload(void)
-{
- int iEtat;
- XFILE *pfile;
- char *line = NULL, *p;
- char *name = NULL;
- TALLOC_CTX *ctx = talloc_init("aix_cache_reload");
-
- if (!ctx) {
- return false;
- }
-
- DEBUG(5, ("reloading aix printcap cache\n"));
-
- if ((pfile = x_fopen(lp_printcapname(), O_RDONLY, 0)) == NULL) {
- DEBUG(0,( "Unable to open qconfig file %s for read!\n", lp_printcapname()));
- TALLOC_FREE(ctx);
- return false;
- }
-
- iEtat = 0;
- /* scan qconfig file for searching <printername>: */
- for (;(line = fgets_slash(NULL, 1024, pfile)); free(line)) {
- if (*line == '*' || *line == 0)
- continue;
-
- switch (iEtat) {
- case 0: /* locate an entry */
- if (*line == '\t' || *line == ' ')
- continue;
-
- if ((p = strchr_m(line, ':'))) {
- char *saveptr;
- *p = '\0';
- p = strtok_r(line, ":", &saveptr);
- if (strcmp(p, "bsh") != 0) {
- name = talloc_strdup(ctx, p);
- if (!name) {
- SAFE_FREE(line);
- x_fclose(pfile);
- TALLOC_FREE(ctx);
- return false;
- }
- iEtat = 1;
- continue;
- }
- }
- break;
-
- case 1: /* scanning device stanza */
- if (*line == '*' || *line == 0)
- continue;
-
- if (*line != '\t' && *line != ' ') {
- /* name is found without stanza device */
- /* probably a good printer ??? */
- iEtat = 0;
- if (!pcap_cache_add(name, NULL)) {
- SAFE_FREE(line);
- x_fclose(pfile);
- TALLOC_FREE(ctx);
- return false;
- }
- continue;
- }
-
- if (strstr_m(line, "backend")) {
- /* it's a device, not a virtual printer */
- iEtat = 0;
- } else if (strstr_m(line, "device")) {
- /* it's a good virtual printer */
- iEtat = 0;
- if (!pcap_cache_add(name, NULL)) {
- SAFE_FREE(line);
- x_fclose(pfile);
- TALLOC_FREE(ctx);
- return false;
- }
- continue;
- }
- break;
- }
- }
-
- x_fclose(pfile);
- TALLOC_FREE(ctx);
- return true;
-}
-
-#else
-/* this keeps fussy compilers happy */
- void print_aix_dummy(void);
- void print_aix_dummy(void) {}
-#endif /* AIX */
+++ /dev/null
-/*
- * Support code for the Common UNIX Printing System ("CUPS")
- *
- * Copyright 1999-2003 by Michael R Sweet.
- * Copyright 2008 Jeremy Allison.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * JRA. Converted to utf8 pull/push.
- */
-
-#include "includes.h"
-#include "printing.h"
-
-#ifdef HAVE_CUPS
-#include <cups/cups.h>
-#include <cups/language.h>
-
-static SIG_ATOMIC_T gotalarm;
-
-/***************************************************************
- Signal function to tell us we timed out.
-****************************************************************/
-
-static void gotalarm_sig(int signum)
-{
- gotalarm = 1;
-}
-
-extern userdom_struct current_user_info;
-
-/*
- * 'cups_passwd_cb()' - The CUPS password callback...
- */
-
-static const char * /* O - Password or NULL */
-cups_passwd_cb(const char *prompt) /* I - Prompt */
-{
- /*
- * Always return NULL to indicate that no password is available...
- */
-
- return (NULL);
-}
-
-static http_t *cups_connect(TALLOC_CTX *frame)
-{
- http_t *http = NULL;
- char *server = NULL, *p = NULL;
- int port;
- int timeout = lp_cups_connection_timeout();
- size_t size;
-
- if (lp_cups_server() != NULL && strlen(lp_cups_server()) > 0) {
- if (!push_utf8_talloc(frame, &server, lp_cups_server(), &size)) {
- return NULL;
- }
- } else {
- server = talloc_strdup(frame,cupsServer());
- }
- if (!server) {
- return NULL;
- }
-
- p = strchr(server, ':');
- if (p) {
- port = atoi(p+1);
- *p = '\0';
- } else {
- port = ippPort();
- }
-
- DEBUG(10, ("connecting to cups server %s:%d\n",
- server, port));
-
- gotalarm = 0;
-
- if (timeout) {
- CatchSignal(SIGALRM, gotalarm_sig);
- alarm(timeout);
- }
-
-#ifdef HAVE_HTTPCONNECTENCRYPT
- http = httpConnectEncrypt(server, port, lp_cups_encrypt());
-#else
- http = httpConnect(server, port);
-#endif
-
-
- CatchSignal(SIGALRM, SIG_IGN);
- alarm(0);
-
- if (http == NULL) {
- DEBUG(0,("Unable to connect to CUPS server %s:%d - %s\n",
- server, port, strerror(errno)));
- }
-
- return http;
-}
-
-static void send_pcap_info(const char *name, const char *info, void *pd)
-{
- int fd = *(int *)pd;
- size_t namelen = name ? strlen(name)+1 : 0;
- size_t infolen = info ? strlen(info)+1 : 0;
-
- DEBUG(11,("send_pcap_info: writing namelen %u\n", (unsigned int)namelen));
- if (sys_write(fd, &namelen, sizeof(namelen)) != sizeof(namelen)) {
- DEBUG(10,("send_pcap_info: namelen write failed %s\n",
- strerror(errno)));
- return;
- }
- DEBUG(11,("send_pcap_info: writing infolen %u\n", (unsigned int)infolen));
- if (sys_write(fd, &infolen, sizeof(infolen)) != sizeof(infolen)) {
- DEBUG(10,("send_pcap_info: infolen write failed %s\n",
- strerror(errno)));
- return;
- }
- if (namelen) {
- DEBUG(11,("send_pcap_info: writing name %s\n", name));
- if (sys_write(fd, name, namelen) != namelen) {
- DEBUG(10,("send_pcap_info: name write failed %s\n",
- strerror(errno)));
- return;
- }
- }
- if (infolen) {
- DEBUG(11,("send_pcap_info: writing info %s\n", info));
- if (sys_write(fd, info, infolen) != infolen) {
- DEBUG(10,("send_pcap_info: info write failed %s\n",
- strerror(errno)));
- return;
- }
- }
-}
-
-static bool cups_cache_reload_async(int fd)
-{
- TALLOC_CTX *frame = talloc_stackframe();
- struct pcap_cache *tmp_pcap_cache = NULL;
- http_t *http = NULL; /* HTTP connection to server */
- ipp_t *request = NULL, /* IPP Request */
- *response = NULL; /* IPP Response */
- ipp_attribute_t *attr; /* Current attribute */
- cups_lang_t *language = NULL; /* Default language */
- char *name, /* printer-name attribute */
- *info; /* printer-info attribute */
- static const char *requested[] =/* Requested attributes */
- {
- "printer-name",
- "printer-info"
- };
- bool ret = False;
- size_t size;
-
- DEBUG(5, ("reloading cups printcap cache\n"));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = cups_connect(frame)) == NULL) {
- goto out;
- }
-
- /*
- * Build a CUPS_GET_PRINTERS request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * requested-attributes
- */
-
- request = ippNew();
-
- request->request.op.operation_id = CUPS_GET_PRINTERS;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requested-attributes",
- (sizeof(requested) / sizeof(requested[0])),
- NULL, requested);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/")) == NULL) {
- DEBUG(0,("Unable to get printer list - %s\n",
- ippErrorString(cupsLastError())));
- goto out;
- }
-
- for (attr = response->attrs; attr != NULL;) {
- /*
- * Skip leading attributes until we hit a printer...
- */
-
- while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
- attr = attr->next;
-
- if (attr == NULL)
- break;
-
- /*
- * Pull the needed attributes from this printer...
- */
-
- name = NULL;
- info = NULL;
-
- while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) {
- if (strcmp(attr->name, "printer-name") == 0 &&
- attr->value_tag == IPP_TAG_NAME) {
- if (!pull_utf8_talloc(frame,
- &name,
- attr->values[0].string.text,
- &size)) {
- goto out;
- }
- }
-
- if (strcmp(attr->name, "printer-info") == 0 &&
- attr->value_tag == IPP_TAG_TEXT) {
- if (!pull_utf8_talloc(frame,
- &info,
- attr->values[0].string.text,
- &size)) {
- goto out;
- }
- }
-
- attr = attr->next;
- }
-
- /*
- * See if we have everything needed...
- */
-
- if (name == NULL)
- break;
-
- if (!pcap_cache_add_specific(&tmp_pcap_cache, name, info)) {
- goto out;
- }
- }
-
- ippDelete(response);
- response = NULL;
-
- /*
- * Build a CUPS_GET_CLASSES request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * requested-attributes
- */
-
- request = ippNew();
-
- request->request.op.operation_id = CUPS_GET_CLASSES;
- request->request.op.request_id = 1;
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requested-attributes",
- (sizeof(requested) / sizeof(requested[0])),
- NULL, requested);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/")) == NULL) {
- DEBUG(0,("Unable to get printer list - %s\n",
- ippErrorString(cupsLastError())));
- goto out;
- }
-
- for (attr = response->attrs; attr != NULL;) {
- /*
- * Skip leading attributes until we hit a printer...
- */
-
- while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
- attr = attr->next;
-
- if (attr == NULL)
- break;
-
- /*
- * Pull the needed attributes from this printer...
- */
-
- name = NULL;
- info = NULL;
-
- while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) {
- if (strcmp(attr->name, "printer-name") == 0 &&
- attr->value_tag == IPP_TAG_NAME) {
- if (!pull_utf8_talloc(frame,
- &name,
- attr->values[0].string.text,
- &size)) {
- goto out;
- }
- }
-
- if (strcmp(attr->name, "printer-info") == 0 &&
- attr->value_tag == IPP_TAG_TEXT) {
- if (!pull_utf8_talloc(frame,
- &info,
- attr->values[0].string.text,
- &size)) {
- goto out;
- }
- }
-
- attr = attr->next;
- }
-
- /*
- * See if we have everything needed...
- */
-
- if (name == NULL)
- break;
-
- if (!pcap_cache_add_specific(&tmp_pcap_cache, name, info)) {
- goto out;
- }
- }
-
- ret = True;
-
- out:
- if (response)
- ippDelete(response);
-
- if (language)
- cupsLangFree(language);
-
- if (http)
- httpClose(http);
-
- /* Send all the entries up the pipe. */
- if (tmp_pcap_cache) {
- pcap_printer_fn_specific(tmp_pcap_cache,
- send_pcap_info,
- (void *)&fd);
-
- pcap_cache_destroy_specific(&tmp_pcap_cache);
- }
- TALLOC_FREE(frame);
- return ret;
-}
-
-static struct pcap_cache *local_pcap_copy;
-struct fd_event *cache_fd_event;
-
-static bool cups_pcap_load_async(int *pfd)
-{
- int fds[2];
- pid_t pid;
-
- *pfd = -1;
-
- if (cache_fd_event) {
- DEBUG(3,("cups_pcap_load_async: already waiting for "
- "a refresh event\n" ));
- return false;
- }
-
- DEBUG(5,("cups_pcap_load_async: asynchronously loading cups printers\n"));
-
- if (pipe(fds) == -1) {
- return false;
- }
-
- pid = sys_fork();
- if (pid == (pid_t)-1) {
- DEBUG(10,("cups_pcap_load_async: fork failed %s\n",
- strerror(errno) ));
- close(fds[0]);
- close(fds[1]);
- return false;
- }
-
- if (pid) {
- DEBUG(10,("cups_pcap_load_async: child pid = %u\n",
- (unsigned int)pid ));
- /* Parent. */
- close(fds[1]);
- *pfd = fds[0];
- return true;
- }
-
- /* Child. */
-
- close_all_print_db();
-
- if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(),
- smbd_event_context(), true))) {
- DEBUG(0,("cups_pcap_load_async: reinit_after_fork() failed\n"));
- smb_panic("cups_pcap_load_async: reinit_after_fork() failed");
- }
-
- close(fds[0]);
- cups_cache_reload_async(fds[1]);
- close(fds[1]);
- _exit(0);
-}
-
-static void cups_async_callback(struct event_context *event_ctx,
- struct fd_event *event,
- uint16 flags,
- void *p)
-{
- TALLOC_CTX *frame = talloc_stackframe();
- int fd = *(int *)p;
- struct pcap_cache *tmp_pcap_cache = NULL;
-
- DEBUG(5,("cups_async_callback: callback received for printer data. "
- "fd = %d\n", fd));
-
- while (1) {
- char *name = NULL, *info = NULL;
- size_t namelen = 0, infolen = 0;
- ssize_t ret = -1;
-
- ret = sys_read(fd, &namelen, sizeof(namelen));
- if (ret == 0) {
- /* EOF */
- break;
- }
- if (ret != sizeof(namelen)) {
- DEBUG(10,("cups_async_callback: namelen read failed %d %s\n",
- errno, strerror(errno)));
- break;
- }
-
- DEBUG(11,("cups_async_callback: read namelen %u\n",
- (unsigned int)namelen));
-
- ret = sys_read(fd, &infolen, sizeof(infolen));
- if (ret == 0) {
- /* EOF */
- break;
- }
- if (ret != sizeof(infolen)) {
- DEBUG(10,("cups_async_callback: infolen read failed %s\n",
- strerror(errno)));
- break;
- }
-
- DEBUG(11,("cups_async_callback: read infolen %u\n",
- (unsigned int)infolen));
-
- if (namelen) {
- name = TALLOC_ARRAY(frame, char, namelen);
- if (!name) {
- break;
- }
- ret = sys_read(fd, name, namelen);
- if (ret == 0) {
- /* EOF */
- break;
- }
- if (ret != namelen) {
- DEBUG(10,("cups_async_callback: name read failed %s\n",
- strerror(errno)));
- break;
- }
- DEBUG(11,("cups_async_callback: read name %s\n",
- name));
- } else {
- name = NULL;
- }
- if (infolen) {
- info = TALLOC_ARRAY(frame, char, infolen);
- if (!info) {
- break;
- }
- ret = sys_read(fd, info, infolen);
- if (ret == 0) {
- /* EOF */
- break;
- }
- if (ret != infolen) {
- DEBUG(10,("cups_async_callback: info read failed %s\n",
- strerror(errno)));
- break;
- }
- DEBUG(11,("cups_async_callback: read info %s\n",
- info));
- } else {
- info = NULL;
- }
-
- /* Add to our local pcap cache. */
- pcap_cache_add_specific(&tmp_pcap_cache, name, info);
- TALLOC_FREE(name);
- TALLOC_FREE(info);
- }
-
- TALLOC_FREE(frame);
- if (tmp_pcap_cache) {
- /* We got a namelist, replace our local cache. */
- pcap_cache_destroy_specific(&local_pcap_copy);
- local_pcap_copy = tmp_pcap_cache;
-
- /* And the systemwide pcap cache. */
- pcap_cache_replace(local_pcap_copy);
- } else {
- DEBUG(2,("cups_async_callback: failed to read a new "
- "printer list\n"));
- }
- close(fd);
- TALLOC_FREE(p);
- TALLOC_FREE(cache_fd_event);
-}
-
-bool cups_cache_reload(void)
-{
- int *p_pipe_fd = TALLOC_P(NULL, int);
-
- if (!p_pipe_fd) {
- return false;
- }
-
- *p_pipe_fd = -1;
-
- /* Set up an async refresh. */
- if (!cups_pcap_load_async(p_pipe_fd)) {
- return false;
- }
- if (!local_pcap_copy) {
- /* We have no local cache, wait directly for
- * async refresh to complete.
- */
- DEBUG(10,("cups_cache_reload: sync read on fd %d\n",
- *p_pipe_fd ));
-
- cups_async_callback(smbd_event_context(),
- NULL,
- EVENT_FD_READ,
- (void *)p_pipe_fd);
- if (!local_pcap_copy) {
- return false;
- }
- } else {
- /* Replace the system cache with our
- * local copy. */
- pcap_cache_replace(local_pcap_copy);
-
- DEBUG(10,("cups_cache_reload: async read on fd %d\n",
- *p_pipe_fd ));
-
- /* Trigger an event when the pipe can be read. */
- cache_fd_event = event_add_fd(smbd_event_context(),
- NULL, *p_pipe_fd,
- EVENT_FD_READ,
- cups_async_callback,
- (void *)p_pipe_fd);
- if (!cache_fd_event) {
- close(*p_pipe_fd);
- TALLOC_FREE(p_pipe_fd);
- return false;
- }
- }
- return true;
-}
-
-/*
- * 'cups_job_delete()' - Delete a job.
- */
-
-static int cups_job_delete(const char *sharename, const char *lprm_command, struct printjob *pjob)
-{
- TALLOC_CTX *frame = talloc_stackframe();
- int ret = 1; /* Return value */
- http_t *http = NULL; /* HTTP connection to server */
- ipp_t *request = NULL, /* IPP Request */
- *response = NULL; /* IPP Response */
- cups_lang_t *language = NULL; /* Default language */
- char *user = NULL;
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- size_t size;
-
- DEBUG(5,("cups_job_delete(%s, %p (%d))\n", sharename, pjob, pjob->sysjob));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = cups_connect(frame)) == NULL) {
- goto out;
- }
-
- /*
- * Build an IPP_CANCEL_JOB request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * job-uri
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_CANCEL_JOB;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/jobs/%d", pjob->sysjob);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
-
- if (!push_utf8_talloc(frame, &user, pjob->user, &size)) {
- goto out;
- }
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, user);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/jobs")) != NULL) {
- if (response->request.status.status_code >= IPP_OK_CONFLICT) {
- DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- } else {
- ret = 0;
- }
- } else {
- DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- }
-
- out:
- if (response)
- ippDelete(response);
-
- if (language)
- cupsLangFree(language);
-
- if (http)
- httpClose(http);
-
- TALLOC_FREE(frame);
- return ret;
-}
-
-
-/*
- * 'cups_job_pause()' - Pause a job.
- */
-
-static int cups_job_pause(int snum, struct printjob *pjob)
-{
- TALLOC_CTX *frame = talloc_stackframe();
- int ret = 1; /* Return value */
- http_t *http = NULL; /* HTTP connection to server */
- ipp_t *request = NULL, /* IPP Request */
- *response = NULL; /* IPP Response */
- cups_lang_t *language = NULL; /* Default language */
- char *user = NULL;
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- size_t size;
-
- DEBUG(5,("cups_job_pause(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = cups_connect(frame)) == NULL) {
- goto out;
- }
-
- /*
- * Build an IPP_HOLD_JOB request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * job-uri
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_HOLD_JOB;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/jobs/%d", pjob->sysjob);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
-
- if (!push_utf8_talloc(frame, &user, pjob->user, &size)) {
- goto out;
- }
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, user);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/jobs")) != NULL) {
- if (response->request.status.status_code >= IPP_OK_CONFLICT) {
- DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- } else {
- ret = 0;
- }
- } else {
- DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- }
-
- out:
- if (response)
- ippDelete(response);
-
- if (language)
- cupsLangFree(language);
-
- if (http)
- httpClose(http);
-
- TALLOC_FREE(frame);
- return ret;
-}
-
-
-/*
- * 'cups_job_resume()' - Resume a paused job.
- */
-
-static int cups_job_resume(int snum, struct printjob *pjob)
-{
- TALLOC_CTX *frame = talloc_stackframe();
- int ret = 1; /* Return value */
- http_t *http = NULL; /* HTTP connection to server */
- ipp_t *request = NULL, /* IPP Request */
- *response = NULL; /* IPP Response */
- cups_lang_t *language = NULL; /* Default language */
- char *user = NULL;
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- size_t size;
-
- DEBUG(5,("cups_job_resume(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = cups_connect(frame)) == NULL) {
- goto out;
- }
-
- /*
- * Build an IPP_RELEASE_JOB request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * job-uri
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_RELEASE_JOB;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/jobs/%d", pjob->sysjob);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
-
- if (!push_utf8_talloc(frame, &user, pjob->user, &size)) {
- goto out;
- }
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, user);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/jobs")) != NULL) {
- if (response->request.status.status_code >= IPP_OK_CONFLICT) {
- DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- } else {
- ret = 0;
- }
- } else {
- DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- }
-
- out:
- if (response)
- ippDelete(response);
-
- if (language)
- cupsLangFree(language);
-
- if (http)
- httpClose(http);
-
- TALLOC_FREE(frame);
- return ret;
-}
-
-
-/*
- * 'cups_job_submit()' - Submit a job for printing.
- */
-
-static int cups_job_submit(int snum, struct printjob *pjob)
-{
- TALLOC_CTX *frame = talloc_stackframe();
- int ret = 1; /* Return value */
- http_t *http = NULL; /* HTTP connection to server */
- ipp_t *request = NULL, /* IPP Request */
- *response = NULL; /* IPP Response */
- ipp_attribute_t *attr_job_id = NULL; /* IPP Attribute "job-id" */
- cups_lang_t *language = NULL; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- const char *clientname = NULL; /* hostname of client for job-originating-host attribute */
- char *new_jobname = NULL;
- int num_options = 0;
- cups_option_t *options = NULL;
- char *printername = NULL;
- char *user = NULL;
- char *jobname = NULL;
- char *cupsoptions = NULL;
- char *filename = NULL;
- size_t size;
- uint32_t jobid = (uint32_t)-1;
- char addr[INET6_ADDRSTRLEN];
-
- DEBUG(5,("cups_job_submit(%d, %p)\n", snum, pjob));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = cups_connect(frame)) == NULL) {
- goto out;
- }
-
- /*
- * Build an IPP_PRINT_JOB request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- * requesting-user-name
- * [document-data]
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_PRINT_JOB;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) {
- goto out;
- }
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
- printername);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
-
- if (!push_utf8_talloc(frame, &user, pjob->user, &size)) {
- goto out;
- }
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, user);
-
- clientname = client_name(get_client_fd());
- if (strcmp(clientname, "UNKNOWN") == 0) {
- clientname = client_addr(get_client_fd(),addr,sizeof(addr));
- }
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "job-originating-host-name", NULL,
- clientname);
-
- /* Get the jobid from the filename. */
- jobid = print_parse_jobid(pjob->filename);
- if (jobid == (uint32_t)-1) {
- DEBUG(0,("cups_job_submit: failed to parse jobid from name %s\n",
- pjob->filename ));
- jobid = 0;
- }
-
- if (!push_utf8_talloc(frame, &jobname, pjob->jobname, &size)) {
- goto out;
- }
- new_jobname = talloc_asprintf(frame,
- "%s%.8u %s", PRINT_SPOOL_PREFIX,
- (unsigned int)jobid,
- jobname);
- if (new_jobname == NULL) {
- goto out;
- }
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
- new_jobname);
-
- /*
- * add any options defined in smb.conf
- */
-
- if (!push_utf8_talloc(frame, &cupsoptions, lp_cups_options(snum), &size)) {
- goto out;
- }
- num_options = 0;
- options = NULL;
- num_options = cupsParseOptions(cupsoptions, num_options, &options);
-
- if ( num_options )
- cupsEncodeOptions(request, num_options, options);
-
- /*
- * Do the request and get back a response...
- */
-
- slprintf(uri, sizeof(uri) - 1, "/printers/%s", printername);
-
- if (!push_utf8_talloc(frame, &filename, pjob->filename, &size)) {
- goto out;
- }
- if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) {
- if (response->request.status.status_code >= IPP_OK_CONFLICT) {
- DEBUG(0,("Unable to print file to %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- } else {
- ret = 0;
- attr_job_id = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER);
- if(attr_job_id) {
- pjob->sysjob = attr_job_id->values[0].integer;
- DEBUG(5,("cups_job_submit: job-id %d\n", pjob->sysjob));
- } else {
- DEBUG(0,("Missing job-id attribute in IPP response"));
- }
- }
- } else {
- DEBUG(0,("Unable to print file to `%s' - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- }
-
- if ( ret == 0 )
- unlink(pjob->filename);
- /* else print_job_end will do it for us */
-
- out:
- if (response)
- ippDelete(response);
-
- if (language)
- cupsLangFree(language);
-
- if (http)
- httpClose(http);
-
- TALLOC_FREE(frame);
-
- return ret;
-}
-
-/*
- * 'cups_queue_get()' - Get all the jobs in the print queue.
- */
-
-static int cups_queue_get(const char *sharename,
- enum printing_types printing_type,
- char *lpq_command,
- print_queue_struct **q,
- print_status_struct *status)
-{
- TALLOC_CTX *frame = talloc_stackframe();
- char *printername = NULL;
- http_t *http = NULL; /* HTTP connection to server */
- ipp_t *request = NULL, /* IPP Request */
- *response = NULL; /* IPP Response */
- ipp_attribute_t *attr = NULL; /* Current attribute */
- cups_lang_t *language = NULL; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- int qcount = 0, /* Number of active queue entries */
- qalloc = 0; /* Number of queue entries allocated */
- print_queue_struct *queue = NULL, /* Queue entries */
- *temp; /* Temporary pointer for queue */
- char *user_name = NULL, /* job-originating-user-name attribute */
- *job_name = NULL; /* job-name attribute */
- int job_id; /* job-id attribute */
- int job_k_octets; /* job-k-octets attribute */
- time_t job_time; /* time-at-creation attribute */
- ipp_jstate_t job_status; /* job-status attribute */
- int job_priority; /* job-priority attribute */
- size_t size;
- static const char *jattrs[] = /* Requested job attributes */
- {
- "job-id",
- "job-k-octets",
- "job-name",
- "job-originating-user-name",
- "job-priority",
- "job-state",
- "time-at-creation",
- };
- static const char *pattrs[] = /* Requested printer attributes */
- {
- "printer-state",
- "printer-state-message"
- };
-
- *q = NULL;
-
- /* HACK ALERT!!! The problem with support the 'printer name'
- option is that we key the tdb off the sharename. So we will
- overload the lpq_command string to pass in the printername
- (which is basically what we do for non-cups printers ... using
- the lpq_command to get the queue listing). */
-
- if (!push_utf8_talloc(frame, &printername, lpq_command, &size)) {
- goto out;
- }
- DEBUG(5,("cups_queue_get(%s, %p, %p)\n", lpq_command, q, status));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = cups_connect(frame)) == NULL) {
- goto out;
- }
-
- /*
- * Generate the printer URI...
- */
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s", printername);
-
- /*
- * Build an IPP_GET_JOBS request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * requested-attributes
- * printer-uri
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_GET_JOBS;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requested-attributes",
- (sizeof(jattrs) / sizeof(jattrs[0])),
- NULL, jattrs);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/")) == NULL) {
- DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
- ippErrorString(cupsLastError())));
- goto out;
- }
-
- if (response->request.status.status_code >= IPP_OK_CONFLICT) {
- DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
- ippErrorString(response->request.status.status_code)));
- goto out;
- }
-
- /*
- * Process the jobs...
- */
-
- qcount = 0;
- qalloc = 0;
- queue = NULL;
-
- for (attr = response->attrs; attr != NULL; attr = attr->next) {
- /*
- * Skip leading attributes until we hit a job...
- */
-
- while (attr != NULL && attr->group_tag != IPP_TAG_JOB)
- attr = attr->next;
-
- if (attr == NULL)
- break;
-
- /*
- * Allocate memory as needed...
- */
- if (qcount >= qalloc) {
- qalloc += 16;
-
- queue = SMB_REALLOC_ARRAY(queue, print_queue_struct, qalloc);
-
- if (queue == NULL) {
- DEBUG(0,("cups_queue_get: Not enough memory!"));
- qcount = 0;
- goto out;
- }
- }
-
- temp = queue + qcount;
- memset(temp, 0, sizeof(print_queue_struct));
-
- /*
- * Pull the needed attributes from this job...
- */
-
- job_id = 0;
- job_priority = 50;
- job_status = IPP_JOB_PENDING;
- job_time = 0;
- job_k_octets = 0;
- user_name = NULL;
- job_name = NULL;
-
- while (attr != NULL && attr->group_tag == IPP_TAG_JOB) {
- if (attr->name == NULL) {
- attr = attr->next;
- break;
- }
-
- if (strcmp(attr->name, "job-id") == 0 &&
- attr->value_tag == IPP_TAG_INTEGER)
- job_id = attr->values[0].integer;
-
- if (strcmp(attr->name, "job-k-octets") == 0 &&
- attr->value_tag == IPP_TAG_INTEGER)
- job_k_octets = attr->values[0].integer;
-
- if (strcmp(attr->name, "job-priority") == 0 &&
- attr->value_tag == IPP_TAG_INTEGER)
- job_priority = attr->values[0].integer;
-
- if (strcmp(attr->name, "job-state") == 0 &&
- attr->value_tag == IPP_TAG_ENUM)
- job_status = (ipp_jstate_t)(attr->values[0].integer);
-
- if (strcmp(attr->name, "time-at-creation") == 0 &&
- attr->value_tag == IPP_TAG_INTEGER)
- job_time = attr->values[0].integer;
-
- if (strcmp(attr->name, "job-name") == 0 &&
- attr->value_tag == IPP_TAG_NAME) {
- if (!pull_utf8_talloc(frame,
- &job_name,
- attr->values[0].string.text,
- &size)) {
- goto out;
- }
- }
-
- if (strcmp(attr->name, "job-originating-user-name") == 0 &&
- attr->value_tag == IPP_TAG_NAME) {
- if (!pull_utf8_talloc(frame,
- &user_name,
- attr->values[0].string.text,
- &size)) {
- goto out;
- }
- }
-
- attr = attr->next;
- }
-
- /*
- * See if we have everything needed...
- */
-
- if (user_name == NULL || job_name == NULL || job_id == 0) {
- if (attr == NULL)
- break;
- else
- continue;
- }
-
- temp->job = job_id;
- temp->size = job_k_octets * 1024;
- temp->status = job_status == IPP_JOB_PENDING ? LPQ_QUEUED :
- job_status == IPP_JOB_STOPPED ? LPQ_PAUSED :
- job_status == IPP_JOB_HELD ? LPQ_PAUSED :
- LPQ_PRINTING;
- temp->priority = job_priority;
- temp->time = job_time;
- strlcpy(temp->fs_user, user_name, sizeof(temp->fs_user));
- strlcpy(temp->fs_file, job_name, sizeof(temp->fs_file));
-
- qcount ++;
-
- if (attr == NULL)
- break;
- }
-
- ippDelete(response);
- response = NULL;
-
- /*
- * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
- * following attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * requested-attributes
- * printer-uri
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
- request->request.op.request_id = 1;
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requested-attributes",
- (sizeof(pattrs) / sizeof(pattrs[0])),
- NULL, pattrs);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/")) == NULL) {
- DEBUG(0,("Unable to get printer status for %s - %s\n", printername,
- ippErrorString(cupsLastError())));
- goto out;
- }
-
- if (response->request.status.status_code >= IPP_OK_CONFLICT) {
- DEBUG(0,("Unable to get printer status for %s - %s\n", printername,
- ippErrorString(response->request.status.status_code)));
- goto out;
- }
-
- /*
- * Get the current printer status and convert it to the SAMBA values.
- */
-
- if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) {
- if (attr->values[0].integer == IPP_PRINTER_STOPPED)
- status->status = LPSTAT_STOPPED;
- else
- status->status = LPSTAT_OK;
- }
-
- if ((attr = ippFindAttribute(response, "printer-state-message",
- IPP_TAG_TEXT)) != NULL) {
- char *msg = NULL;
- if (!pull_utf8_talloc(frame, &msg,
- attr->values[0].string.text,
- &size)) {
- SAFE_FREE(queue);
- qcount = 0;
- goto out;
- }
- fstrcpy(status->message, msg);
- }
-
- out:
-
- /*
- * Return the job queue...
- */
-
- *q = queue;
-
- if (response)
- ippDelete(response);
-
- if (language)
- cupsLangFree(language);
-
- if (http)
- httpClose(http);
-
- TALLOC_FREE(frame);
- return qcount;
-}
-
-
-/*
- * 'cups_queue_pause()' - Pause a print queue.
- */
-
-static int cups_queue_pause(int snum)
-{
- TALLOC_CTX *frame = talloc_stackframe();
- int ret = 1; /* Return value */
- http_t *http = NULL; /* HTTP connection to server */
- ipp_t *request = NULL, /* IPP Request */
- *response = NULL; /* IPP Response */
- cups_lang_t *language = NULL; /* Default language */
- char *printername = NULL;
- char *username = NULL;
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- size_t size;
-
- DEBUG(5,("cups_queue_pause(%d)\n", snum));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = cups_connect(frame)) == NULL) {
- goto out;
- }
-
- /*
- * Build an IPP_PAUSE_PRINTER request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_PAUSE_PRINTER;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) {
- goto out;
- }
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
- printername);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
-
- if (!push_utf8_talloc(frame, &username, current_user_info.unix_name, &size)) {
- goto out;
- }
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, username);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) {
- if (response->request.status.status_code >= IPP_OK_CONFLICT) {
- DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- } else {
- ret = 0;
- }
- } else {
- DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- }
-
- out:
- if (response)
- ippDelete(response);
-
- if (language)
- cupsLangFree(language);
-
- if (http)
- httpClose(http);
-
- TALLOC_FREE(frame);
- return ret;
-}
-
-
-/*
- * 'cups_queue_resume()' - Restart a print queue.
- */
-
-static int cups_queue_resume(int snum)
-{
- TALLOC_CTX *frame = talloc_stackframe();
- int ret = 1; /* Return value */
- http_t *http = NULL; /* HTTP connection to server */
- ipp_t *request = NULL, /* IPP Request */
- *response = NULL; /* IPP Response */
- cups_lang_t *language = NULL; /* Default language */
- char *printername = NULL;
- char *username = NULL;
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- size_t size;
-
- DEBUG(5,("cups_queue_resume(%d)\n", snum));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = cups_connect(frame)) == NULL) {
- goto out;
- }
-
- /*
- * Build an IPP_RESUME_PRINTER request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_RESUME_PRINTER;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) {
- goto out;
- }
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
- printername);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
-
- if (!push_utf8_talloc(frame, &username, current_user_info.unix_name, &size)) {
- goto out;
- }
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, username);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) {
- if (response->request.status.status_code >= IPP_OK_CONFLICT) {
- DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- } else {
- ret = 0;
- }
- } else {
- DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- }
-
- out:
- if (response)
- ippDelete(response);
-
- if (language)
- cupsLangFree(language);
-
- if (http)
- httpClose(http);
-
- TALLOC_FREE(frame);
- return ret;
-}
-
-/*******************************************************************
- * CUPS printing interface definitions...
- ******************************************************************/
-
-struct printif cups_printif =
-{
- PRINT_CUPS,
- cups_queue_get,
- cups_queue_pause,
- cups_queue_resume,
- cups_job_delete,
- cups_job_pause,
- cups_job_resume,
- cups_job_submit,
-};
-
-bool cups_pull_comment_location(TALLOC_CTX *mem_ctx,
- const char *printername,
- char **comment,
- char **location)
-{
- TALLOC_CTX *frame = talloc_stackframe();
- http_t *http = NULL; /* HTTP connection to server */
- ipp_t *request = NULL, /* IPP Request */
- *response = NULL; /* IPP Response */
- ipp_attribute_t *attr; /* Current attribute */
- cups_lang_t *language = NULL; /* Default language */
- char uri[HTTP_MAX_URI];
- char *server = NULL;
- char *sharename = NULL;
- char *name = NULL;
- static const char *requested[] =/* Requested attributes */
- {
- "printer-name",
- "printer-info",
- "printer-location"
- };
- bool ret = False;
- size_t size;
-
- DEBUG(5, ("pulling %s location\n", printername));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = cups_connect(frame)) == NULL) {
- goto out;
- }
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- if (lp_cups_server() != NULL && strlen(lp_cups_server()) > 0) {
- if (!push_utf8_talloc(frame, &server, lp_cups_server(), &size)) {
- goto out;
- }
- } else {
- server = talloc_strdup(frame,cupsServer());
- }
- if (server) {
- goto out;
- }
- if (!push_utf8_talloc(frame, &sharename, printername, &size)) {
- goto out;
- }
- slprintf(uri, sizeof(uri) - 1, "ipp://%s/printers/%s",
- server, sharename);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
-
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requested-attributes",
- (sizeof(requested) / sizeof(requested[0])),
- NULL, requested);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/")) == NULL) {
- DEBUG(0,("Unable to get printer attributes - %s\n",
- ippErrorString(cupsLastError())));
- goto out;
- }
-
- for (attr = response->attrs; attr != NULL;) {
- /*
- * Skip leading attributes until we hit a printer...
- */
-
- while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
- attr = attr->next;
-
- if (attr == NULL)
- break;
-
- /*
- * Pull the needed attributes from this printer...
- */
-
- while ( attr && (attr->group_tag == IPP_TAG_PRINTER) ) {
- if (strcmp(attr->name, "printer-name") == 0 &&
- attr->value_tag == IPP_TAG_NAME) {
- if (!pull_utf8_talloc(frame,
- &name,
- attr->values[0].string.text,
- &size)) {
- goto out;
- }
- }
-
- /* Grab the comment if we don't have one */
- if ( (strcmp(attr->name, "printer-info") == 0)
- && (attr->value_tag == IPP_TAG_TEXT))
- {
- if (!pull_utf8_talloc(mem_ctx,
- comment,
- attr->values[0].string.text,
- &size)) {
- goto out;
- }
- DEBUG(5,("cups_pull_comment_location: Using cups comment: %s\n",
- *comment));
- }
-
- /* Grab the location if we don't have one */
- if ( (strcmp(attr->name, "printer-location") == 0)
- && (attr->value_tag == IPP_TAG_TEXT))
- {
- if (!pull_utf8_talloc(mem_ctx,
- location,
- attr->values[0].string.text,
- &size)) {
- goto out;
- }
- DEBUG(5,("cups_pull_comment_location: Using cups location: %s\n",
- *location));
- }
-
- attr = attr->next;
- }
-
- /*
- * We have everything needed...
- */
-
- if (name != NULL)
- break;
- }
-
- ret = True;
-
- out:
- if (response)
- ippDelete(response);
-
- if (request) {
- ippDelete(request);
- }
-
- if (language)
- cupsLangFree(language);
-
- if (http)
- httpClose(http);
-
- TALLOC_FREE(frame);
- return ret;
-}
-
-#else
- /* this keeps fussy compilers happy */
- void print_cups_dummy(void);
- void print_cups_dummy(void) {}
-#endif /* HAVE_CUPS */
+++ /dev/null
-/*
- Unix SMB/CIFS implementation.
- printing command routines
- Copyright (C) Andrew Tridgell 1992-2000
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "printing.h"
-
-extern struct current_user current_user;
-extern userdom_struct current_user_info;
-
-/****************************************************************************
- Run a given print command
- a null terminated list of value/substitute pairs is provided
- for local substitution strings
-****************************************************************************/
-static int print_run_command(int snum, const char* printername, bool do_sub,
- const char *command, int *outfd, ...)
-{
- char *syscmd;
- char *arg;
- int ret;
- TALLOC_CTX *ctx = talloc_tos();
- va_list ap;
- va_start(ap, outfd);
-
- /* check for a valid system printername and valid command to run */
-
- if ( !printername || !*printername ) {
- va_end(ap);
- return -1;
- }
-
- if (!command || !*command) {
- va_end(ap);
- return -1;
- }
-
- syscmd = talloc_strdup(ctx, command);
- if (!syscmd) {
- va_end(ap);
- return -1;
- }
-
- while ((arg = va_arg(ap, char *))) {
- char *value = va_arg(ap,char *);
- syscmd = talloc_string_sub(ctx, syscmd, arg, value);
- if (!syscmd) {
- va_end(ap);
- return -1;
- }
- }
- va_end(ap);
-
- syscmd = talloc_string_sub(ctx, syscmd, "%p", printername);
- if (!syscmd) {
- return -1;
- }
-
- if (do_sub && snum != -1) {
- syscmd = talloc_sub_advanced(ctx,
- lp_servicename(snum),
- current_user_info.unix_name,
- "",
- current_user.ut.gid,
- get_current_username(),
- current_user_info.domain,
- syscmd);
- if (!syscmd) {
- return -1;
- }
- }
-
- ret = smbrun_no_sanitize(syscmd,outfd);
-
- DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
-
- return ret;
-}
-
-
-/****************************************************************************
-delete a print job
-****************************************************************************/
-static int generic_job_delete( const char *sharename, const char *lprm_command, struct printjob *pjob)
-{
- fstring jobstr;
-
- /* need to delete the spooled entry */
- slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
- return print_run_command( -1, sharename, False, lprm_command, NULL,
- "%j", jobstr,
- "%T", http_timestring(talloc_tos(), pjob->starttime),
- NULL);
-}
-
-/****************************************************************************
-pause a job
-****************************************************************************/
-static int generic_job_pause(int snum, struct printjob *pjob)
-{
- fstring jobstr;
-
- /* need to pause the spooled entry */
- slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
- return print_run_command(snum, PRINTERNAME(snum), True,
- lp_lppausecommand(snum), NULL,
- "%j", jobstr,
- NULL);
-}
-
-/****************************************************************************
-resume a job
-****************************************************************************/
-static int generic_job_resume(int snum, struct printjob *pjob)
-{
- fstring jobstr;
-
- /* need to pause the spooled entry */
- slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
- return print_run_command(snum, PRINTERNAME(snum), True,
- lp_lpresumecommand(snum), NULL,
- "%j", jobstr,
- NULL);
-}
-
-/****************************************************************************
- Submit a file for printing - called from print_job_end()
-****************************************************************************/
-
-static int generic_job_submit(int snum, struct printjob *pjob)
-{
- int ret = -1;
- char *current_directory = NULL;
- char *print_directory = NULL;
- char *wd = NULL;
- char *p = NULL;
- char *jobname = NULL;
- TALLOC_CTX *ctx = talloc_tos();
- fstring job_page_count, job_size;
-
- /* we print from the directory path to give the best chance of
- parsing the lpq output */
- current_directory = TALLOC_ARRAY(ctx,
- char,
- PATH_MAX+1);
- if (!current_directory) {
- return -1;
- }
- wd = sys_getwd(current_directory);
- if (!wd) {
- return -1;
- }
-
- print_directory = talloc_strdup(ctx, pjob->filename);
- if (!print_directory) {
- return -1;
- }
- p = strrchr_m(print_directory,'/');
- if (!p) {
- return -1;
- }
- *p++ = 0;
-
- if (chdir(print_directory) != 0) {
- return -1;
- }
-
- jobname = talloc_strdup(ctx, pjob->jobname);
- if (!jobname) {
- ret = -1;
- goto out;
- }
- jobname = talloc_string_sub(ctx, jobname, "'", "_");
- if (!jobname) {
- ret = -1;
- goto out;
- }
- slprintf(job_page_count, sizeof(job_page_count)-1, "%d", pjob->page_count);
- slprintf(job_size, sizeof(job_size)-1, "%lu", (unsigned long)pjob->size);
-
- /* send it to the system spooler */
- ret = print_run_command(snum, PRINTERNAME(snum), True,
- lp_printcommand(snum), NULL,
- "%s", p,
- "%J", jobname,
- "%f", p,
- "%z", job_size,
- "%c", job_page_count,
- NULL);
-
- out:
-
- if (chdir(wd) == -1) {
- smb_panic("chdir failed in generic_job_submit");
- }
- TALLOC_FREE(current_directory);
- return ret;
-}
-
-
-/****************************************************************************
-get the current list of queued jobs
-****************************************************************************/
-static int generic_queue_get(const char *printer_name,
- enum printing_types printing_type,
- char *lpq_command,
- print_queue_struct **q,
- print_status_struct *status)
-{
- char **qlines;
- int fd;
- int numlines, i, qcount;
- print_queue_struct *queue = NULL;
-
- /* never do substitution when running the 'lpq command' since we can't
- get it rigt when using the background update daemon. Make the caller
- do it before passing off the command string to us here. */
-
- print_run_command(-1, printer_name, False, lpq_command, &fd, NULL);
-
- if (fd == -1) {
- DEBUG(5,("generic_queue_get: Can't read print queue status for printer %s\n",
- printer_name ));
- return 0;
- }
-
- numlines = 0;
- qlines = fd_lines_load(fd, &numlines,0,NULL);
- close(fd);
-
- /* turn the lpq output into a series of job structures */
- qcount = 0;
- ZERO_STRUCTP(status);
- if (numlines && qlines) {
- queue = SMB_MALLOC_ARRAY(print_queue_struct, numlines+1);
- if (!queue) {
- TALLOC_FREE(qlines);
- *q = NULL;
- return 0;
- }
- memset(queue, '\0', sizeof(print_queue_struct)*(numlines+1));
-
- for (i=0; i<numlines; i++) {
- /* parse the line */
- if (parse_lpq_entry(printing_type,qlines[i],
- &queue[qcount],status,qcount==0)) {
- qcount++;
- }
- }
- }
-
- TALLOC_FREE(qlines);
- *q = queue;
- return qcount;
-}
-
-/****************************************************************************
- pause a queue
-****************************************************************************/
-static int generic_queue_pause(int snum)
-{
- return print_run_command(snum, PRINTERNAME(snum), True, lp_queuepausecommand(snum), NULL, NULL);
-}
-
-/****************************************************************************
- resume a queue
-****************************************************************************/
-static int generic_queue_resume(int snum)
-{
- return print_run_command(snum, PRINTERNAME(snum), True, lp_queueresumecommand(snum), NULL, NULL);
-}
-
-/****************************************************************************
- * Generic printing interface definitions...
- ***************************************************************************/
-
-struct printif generic_printif =
-{
- DEFAULT_PRINTING,
- generic_queue_get,
- generic_queue_pause,
- generic_queue_resume,
- generic_job_delete,
- generic_job_pause,
- generic_job_resume,
- generic_job_submit,
-};
-
+++ /dev/null
-/*
- * Support code for Novell iPrint using the Common UNIX Printing
- * System ("CUPS") libraries
- *
- * Copyright 1999-2003 by Michael R Sweet.
- * Portions Copyright 2005 by Joel J. Smith.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "includes.h"
-#include "printing.h"
-
-#ifdef HAVE_IPRINT
-#include <cups/cups.h>
-#include <cups/language.h>
-
-#define OPERATION_NOVELL_LIST_PRINTERS 0x401A
-#define OPERATION_NOVELL_MGMT 0x401C
-#define NOVELL_SERVER_SYSNAME "sysname="
-#define NOVELL_SERVER_SYSNAME_NETWARE "NetWare IA32"
-#define NOVELL_SERVER_VERSION_STRING "iprintserverversion="
-#define NOVELL_SERVER_VERSION_OES_SP1 33554432
-
-/*
- * 'iprint_passwd_cb()' - The iPrint password callback...
- */
-
-static const char * /* O - Password or NULL */
-iprint_passwd_cb(const char *prompt) /* I - Prompt */
-{
- /*
- * Always return NULL to indicate that no password is available...
- */
-
- return (NULL);
-}
-
-static const char *iprint_server(void)
-{
- if ((lp_iprint_server() != NULL) && (strlen(lp_iprint_server()) > 0)) {
- DEBUG(10, ("iprint server explicitly set to %s\n",
- lp_iprint_server()));
- return lp_iprint_server();
- }
-
- DEBUG(10, ("iprint server left to default %s\n", cupsServer()));
- return cupsServer();
-}
-
-/*
- * Pass in an already connected http_t*
- * Returns the server version if one can be found, multiplied by
- * -1 for all NetWare versions. Returns 0 if a server version
- * cannot be determined
- */
-
-static int iprint_get_server_version(http_t *http, char* serviceUri)
-{
- ipp_t *request = NULL, /* IPP Request */
- *response = NULL; /* IPP Response */
- ipp_attribute_t *attr; /* Current attribute */
- cups_lang_t *language = NULL; /* Default language */
- char *ver; /* server version pointer */
- char *vertmp; /* server version tmp pointer */
- int serverVersion = 0; /* server version */
- char *os; /* server os */
- int osFlag = 0; /* 0 for NetWare, 1 for anything else */
- char *temp; /* pointer for string manipulation */
-
- /*
- * Build an OPERATION_NOVELL_MGMT("get-server-version") request,
- * which requires the following attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * operation-name
- * service-uri
- */
-
- request = ippNew();
-
- request->request.op.operation_id = (ipp_op_t)OPERATION_NOVELL_MGMT;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "service-uri", NULL, serviceUri);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
- "operation-name", NULL, "get-server-version");
-
- /*
- * Do the request and get back a response...
- */
-
- if (((response = cupsDoRequest(http, request, "/ipp/")) == NULL) ||
- (response->request.status.status_code >= IPP_OK_CONFLICT))
- goto out;
-
- if (((attr = ippFindAttribute(response, "server-version",
- IPP_TAG_STRING)) != NULL)) {
- if ((ver = strstr(attr->values[0].string.text,
- NOVELL_SERVER_VERSION_STRING)) != NULL) {
- ver += strlen(NOVELL_SERVER_VERSION_STRING);
- /*
- * Strangely, libcups stores a IPP_TAG_STRING (octet
- * string) as a null-terminated string with no length
- * even though it could be binary data with nulls in
- * it. Luckily, in this case the value is not binary.
- */
- serverVersion = strtol(ver, &vertmp, 10);
-
- /* Check for not found, overflow or negative version */
- if ((ver == vertmp) || (serverVersion < 0))
- serverVersion = 0;
- }
-
- if ((os = strstr(attr->values[0].string.text,
- NOVELL_SERVER_SYSNAME)) != NULL) {
- os += strlen(NOVELL_SERVER_SYSNAME);
- if ((temp = strchr(os,'<')) != NULL)
- *temp = '\0';
- if (strcmp(os,NOVELL_SERVER_SYSNAME_NETWARE))
- osFlag = 1; /* 1 for non-NetWare systems */
- }
- }
-
- out:
- if (response)
- ippDelete(response);
-
- if (language)
- cupsLangFree(language);
-
- if (osFlag == 0)
- serverVersion *= -1;
-
- return serverVersion;
-}
-
-
-static int iprint_cache_add_printer(http_t *http,
- int reqId,
- char* url)
-{
- ipp_t *request = NULL, /* IPP Request */
- *response = NULL; /* IPP Response */
- ipp_attribute_t *attr; /* Current attribute */
- cups_lang_t *language = NULL; /* Default language */
- char *name, /* printer-name attribute */
- *info, /* printer-info attribute */
- smb_enabled, /* smb-enabled attribute */
- secure; /* security-enabled attrib. */
-
- char *httpPath; /* path portion of the printer-uri */
-
- static const char *pattrs[] = /* Requested printer attributes */
- {
- "printer-name",
- "security-enabled",
- "printer-info",
- "smb-enabled"
- };
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
- request->request.op.request_id = reqId;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, url);
-
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
- "requested-attributes",
- (sizeof(pattrs) / sizeof(pattrs[0])),
- NULL, pattrs);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((httpPath = strstr(url,"://")) == NULL ||
- (httpPath = strchr(httpPath+3,'/')) == NULL)
- {
- ippDelete(request);
- request = NULL;
- goto out;
- }
-
- if ((response = cupsDoRequest(http, request, httpPath)) == NULL) {
- ipp_status_t lastErr = cupsLastError();
-
- /*
- * Ignore printers that cannot be queried without credentials
- */
- if (lastErr == IPP_FORBIDDEN ||
- lastErr == IPP_NOT_AUTHENTICATED ||
- lastErr == IPP_NOT_AUTHORIZED)
- goto out;
-
- DEBUG(0,("Unable to get printer list - %s\n",
- ippErrorString(lastErr)));
- goto out;
- }
-
- for (attr = response->attrs; attr != NULL;) {
- /*
- * Skip leading attributes until we hit a printer...
- */
-
- while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
- attr = attr->next;
-
- if (attr == NULL)
- break;
-
- /*
- * Pull the needed attributes from this printer...
- */
-
- name = NULL;
- info = NULL;
- smb_enabled= 1;
- secure = 0;
-
- while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) {
- if (strcmp(attr->name, "printer-name") == 0 &&
- attr->value_tag == IPP_TAG_NAME)
- name = attr->values[0].string.text;
-
- if (strcmp(attr->name, "printer-info") == 0 &&
- (attr->value_tag == IPP_TAG_TEXT ||
- attr->value_tag == IPP_TAG_TEXTLANG))
- info = attr->values[0].string.text;
-
- /*
- * If the smb-enabled attribute is present and the
- * value is set to 0, don't show the printer.
- * If the attribute is not present, assume that the
- * printer should show up
- */
- if (!strcmp(attr->name, "smb-enabled") &&
- ((attr->value_tag == IPP_TAG_INTEGER &&
- !attr->values[0].integer) ||
- (attr->value_tag == IPP_TAG_BOOLEAN &&
- !attr->values[0].boolean)))
- smb_enabled = 0;
-
- /*
- * If the security-enabled attribute is present and the
- * value is set to 1, don't show the printer.
- * If the attribute is not present, assume that the
- * printer should show up
- */
- if (!strcmp(attr->name, "security-enabled") &&
- ((attr->value_tag == IPP_TAG_INTEGER &&
- attr->values[0].integer) ||
- (attr->value_tag == IPP_TAG_BOOLEAN &&
- attr->values[0].boolean)))
- secure = 1;
-
- attr = attr->next;
- }
-
- /*
- * See if we have everything needed...
- * Make sure the printer is not a secure printer
- * and make sure smb printing hasn't been explicitly
- * disabled for the printer
- */
-
- if (name != NULL && !secure && smb_enabled)
- pcap_cache_add(name, info);
- }
-
- out:
- if (response)
- ippDelete(response);
- return(0);
-}
-
-bool iprint_cache_reload(void)
-{
- http_t *http = NULL; /* HTTP connection to server */
- ipp_t *request = NULL, /* IPP Request */
- *response = NULL; /* IPP Response */
- ipp_attribute_t *attr; /* Current attribute */
- cups_lang_t *language = NULL; /* Default language */
- int i;
- bool ret = False;
-
- DEBUG(5, ("reloading iprint printcap cache\n"));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(iprint_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(iprint_server(), ippPort())) == NULL) {
- DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
- iprint_server(), strerror(errno)));
- goto out;
- }
-
- /*
- * Build a OPERATION_NOVELL_LIST_PRINTERS request, which requires the following attributes:
- *
- * attributes-charset
- * attributes-natural-language
- */
-
- request = ippNew();
-
- request->request.op.operation_id =
- (ipp_op_t)OPERATION_NOVELL_LIST_PRINTERS;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
- "ipp-server", NULL, "ippSrvr");
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/ipp")) == NULL) {
- DEBUG(0,("Unable to get printer list - %s\n",
- ippErrorString(cupsLastError())));
- goto out;
- }
-
- for (attr = response->attrs; attr != NULL;) {
- /*
- * Skip leading attributes until we hit a printer...
- */
-
- while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
- attr = attr->next;
-
- if (attr == NULL)
- break;
-
- /*
- * Pull the needed attributes from this printer...
- */
-
- while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
- {
- if (strcmp(attr->name, "printer-name") == 0 &&
- (attr->value_tag == IPP_TAG_URI ||
- attr->value_tag == IPP_TAG_NAME ||
- attr->value_tag == IPP_TAG_TEXT ||
- attr->value_tag == IPP_TAG_NAMELANG ||
- attr->value_tag == IPP_TAG_TEXTLANG))
- {
- for (i = 0; i<attr->num_values; i++)
- {
- char *url = attr->values[i].string.text;
- if (!url || !strlen(url))
- continue;
- iprint_cache_add_printer(http, i+2, url);
- }
- }
- attr = attr->next;
- }
- }
-
- ret = True;
-
- out:
- if (response)
- ippDelete(response);
-
- if (language)
- cupsLangFree(language);
-
- if (http)
- httpClose(http);
-
- return ret;
-}
-
-
-/*
- * 'iprint_job_delete()' - Delete a job.
- */
-
-static int iprint_job_delete(const char *sharename, const char *lprm_command, struct printjob *pjob)
-{
- int ret = 1; /* Return value */
- http_t *http = NULL; /* HTTP connection to server */
- ipp_t *request = NULL, /* IPP Request */
- *response = NULL; /* IPP Response */
- cups_lang_t *language = NULL; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- char httpPath[HTTP_MAX_URI]; /* path portion of the printer-uri */
-
-
- DEBUG(5,("iprint_job_delete(%s, %p (%d))\n", sharename, pjob, pjob->sysjob));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(iprint_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(iprint_server(), ippPort())) == NULL) {
- DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
- iprint_server(), strerror(errno)));
- goto out;
- }
-
- /*
- * Build an IPP_CANCEL_JOB request, which uses the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- * job-id
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_CANCEL_JOB;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), sharename);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
-
- ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", pjob->sysjob);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, pjob->user);
-
- /*
- * Do the request and get back a response...
- */
-
- slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", sharename);
-
- if ((response = cupsDoRequest(http, request, httpPath)) != NULL) {
- if (response->request.status.status_code >= IPP_OK_CONFLICT) {
- DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- } else {
- ret = 0;
- }
- } else {
- DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- }
-
- out:
- if (response)
- ippDelete(response);
-
- if (language)
- cupsLangFree(language);
-
- if (http)
- httpClose(http);
-
- return ret;
-}
-
-
-/*
- * 'iprint_job_pause()' - Pause a job.
- */
-
-static int iprint_job_pause(int snum, struct printjob *pjob)
-{
- int ret = 1; /* Return value */
- http_t *http = NULL; /* HTTP connection to server */
- ipp_t *request = NULL, /* IPP Request */
- *response = NULL; /* IPP Response */
- cups_lang_t *language = NULL; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- char httpPath[HTTP_MAX_URI]; /* path portion of the printer-uri */
-
-
- DEBUG(5,("iprint_job_pause(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(iprint_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(iprint_server(), ippPort())) == NULL) {
- DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
- iprint_server(), strerror(errno)));
- goto out;
- }
-
- /*
- * Build an IPP_HOLD_JOB request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- * job-id
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_HOLD_JOB;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), PRINTERNAME(snum));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
-
- ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", pjob->sysjob);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, pjob->user);
-
- /*
- * Do the request and get back a response...
- */
-
- slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", PRINTERNAME(snum));
-
- if ((response = cupsDoRequest(http, request, httpPath)) != NULL) {
- if (response->request.status.status_code >= IPP_OK_CONFLICT) {
- DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- } else {
- ret = 0;
- }
- } else {
- DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- }
-
- out:
- if (response)
- ippDelete(response);
-
- if (language)
- cupsLangFree(language);
-
- if (http)
- httpClose(http);
-
- return ret;
-}
-
-
-/*
- * 'iprint_job_resume()' - Resume a paused job.
- */
-
-static int iprint_job_resume(int snum, struct printjob *pjob)
-{
- int ret = 1; /* Return value */
- http_t *http = NULL; /* HTTP connection to server */
- ipp_t *request = NULL, /* IPP Request */
- *response = NULL; /* IPP Response */
- cups_lang_t *language = NULL; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- char httpPath[HTTP_MAX_URI]; /* path portion of the printer-uri */
-
-
- DEBUG(5,("iprint_job_resume(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(iprint_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(iprint_server(), ippPort())) == NULL) {
- DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
- iprint_server(), strerror(errno)));
- goto out;
- }
-
- /*
- * Build an IPP_RELEASE_JOB request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- * job-id
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_RELEASE_JOB;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), PRINTERNAME(snum));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
-
- ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", pjob->sysjob);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, pjob->user);
-
- /*
- * Do the request and get back a response...
- */
-
- slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", PRINTERNAME(snum));
-
- if ((response = cupsDoRequest(http, request, httpPath)) != NULL) {
- if (response->request.status.status_code >= IPP_OK_CONFLICT) {
- DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- } else {
- ret = 0;
- }
- } else {
- DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- }
-
- out:
- if (response)
- ippDelete(response);
-
- if (language)
- cupsLangFree(language);
-
- if (http)
- httpClose(http);
-
- return ret;
-}
-
-
-/*
- * 'iprint_job_submit()' - Submit a job for printing.
- */
-
-static int iprint_job_submit(int snum, struct printjob *pjob)
-{
- int ret = 1; /* Return value */
- http_t *http = NULL; /* HTTP connection to server */
- ipp_t *request = NULL, /* IPP Request */
- *response = NULL; /* IPP Response */
- ipp_attribute_t *attr; /* Current attribute */
- cups_lang_t *language = NULL; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- const char *clientname = NULL; /* hostname of client for job-originating-host attribute */
- char addr[INET6_ADDRSTRLEN];
-
- DEBUG(5,("iprint_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(iprint_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(iprint_server(), ippPort())) == NULL) {
- DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
- iprint_server(), strerror(errno)));
- goto out;
- }
-
- /*
- * Build an IPP_PRINT_JOB request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- * requesting-user-name
- * [document-data]
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_PRINT_JOB;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), PRINTERNAME(snum));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, pjob->user);
-
- clientname = client_name(get_client_fd());
- if (strcmp(clientname, "UNKNOWN") == 0) {
- clientname = client_addr(get_client_fd(),addr,sizeof(addr));
- }
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "job-originating-host-name", NULL,
- clientname);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
- pjob->jobname);
-
- /*
- * Do the request and get back a response...
- */
-
- slprintf(uri, sizeof(uri) - 1, "/ipp/%s", PRINTERNAME(snum));
-
- if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) {
- if (response->request.status.status_code >= IPP_OK_CONFLICT) {
- DEBUG(0,("Unable to print file to %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- } else {
- ret = 0;
- }
- } else {
- DEBUG(0,("Unable to print file to `%s' - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- }
-
- if ( ret == 0 )
- unlink(pjob->filename);
- /* else print_job_end will do it for us */
-
- if ( ret == 0 ) {
-
- attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER);
- if (attr != NULL && attr->group_tag == IPP_TAG_JOB)
- {
- pjob->sysjob = attr->values[0].integer;
- }
- }
-
- out:
- if (response)
- ippDelete(response);
-
- if (language)
- cupsLangFree(language);
-
- if (http)
- httpClose(http);
-
- return ret;
-}
-
-/*
- * 'iprint_queue_get()' - Get all the jobs in the print queue.
- */
-
-static int iprint_queue_get(const char *sharename,
- enum printing_types printing_type,
- char *lpq_command,
- print_queue_struct **q,
- print_status_struct *status)
-{
- fstring printername;
- http_t *http = NULL; /* HTTP connection to server */
- ipp_t *request = NULL, /* IPP Request */
- *response = NULL; /* IPP Response */
- ipp_attribute_t *attr = NULL; /* Current attribute */
- cups_lang_t *language = NULL; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- char serviceUri[HTTP_MAX_URI]; /* service-uri attribute */
- char httpPath[HTTP_MAX_URI]; /* path portion of the uri */
- int jobUseUnixTime = 0; /* Whether job times should
- * be assumed to be Unix time */
- int qcount = 0, /* Number of active queue entries */
- qalloc = 0; /* Number of queue entries allocated */
- print_queue_struct *queue = NULL, /* Queue entries */
- *temp; /* Temporary pointer for queue */
- const char *user_name, /* job-originating-user-name attribute */
- *job_name; /* job-name attribute */
- int job_id; /* job-id attribute */
- int job_k_octets; /* job-k-octets attribute */
- time_t job_time; /* time-at-creation attribute */
- time_t printer_current_time = 0; /* printer's current time */
- time_t printer_up_time = 0; /* printer's uptime */
- ipp_jstate_t job_status; /* job-status attribute */
- int job_priority; /* job-priority attribute */
- static const char *jattrs[] = /* Requested job attributes */
- {
- "job-id",
- "job-k-octets",
- "job-name",
- "job-originating-user-name",
- "job-priority",
- "job-state",
- "time-at-creation",
- };
- static const char *pattrs[] = /* Requested printer attributes */
- {
- "printer-state",
- "printer-state-message",
- "printer-current-time",
- "printer-up-time"
- };
-
- *q = NULL;
-
- /* HACK ALERT!!! The porblem with support the 'printer name'
- option is that we key the tdb off the sharename. So we will
- overload the lpq_command string to pass in the printername
- (which is basically what we do for non-cups printers ... using
- the lpq_command to get the queue listing). */
-
- fstrcpy( printername, lpq_command );
-
- DEBUG(5,("iprint_queue_get(%s, %p, %p)\n", printername, q, status));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(iprint_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(iprint_server(), ippPort())) == NULL) {
- DEBUG(0,("Unable to connect to iPrint server %s - %s\n",
- iprint_server(), strerror(errno)));
- goto out;
- }
-
- /*
- * Generate the printer URI and the service URI that goes with it...
- */
-
- slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), printername);
- slprintf(serviceUri, sizeof(serviceUri) - 1, "ipp://%s/ipp/", iprint_server());
-
- /*
- * For Linux iPrint servers from OES SP1 on, the iPrint server
- * uses Unix time for job start times unless it detects the iPrint
- * client in an http User-Agent header. (This was done to accomodate
- * CUPS broken behavior. According to RFC 2911, section 4.3.14, job
- * start times are supposed to be relative to how long the printer has
- * been up.) Since libcups doesn't allow us to set that header before
- * the request is sent, this ugly hack allows us to detect the server
- * version and decide how to interpret the job time.
- */
- if (iprint_get_server_version(http, serviceUri) >=
- NOVELL_SERVER_VERSION_OES_SP1)
- jobUseUnixTime = 1;
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
- request->request.op.request_id = 2;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
-
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
- "requested-attributes",
- (sizeof(pattrs) / sizeof(pattrs[0])),
- NULL, pattrs);
-
- /*
- * Do the request and get back a response...
- */
-
- slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", printername);
-
- if ((response = cupsDoRequest(http, request, httpPath)) == NULL) {
- DEBUG(0,("Unable to get printer status for %s - %s\n", printername,
- ippErrorString(cupsLastError())));
- *q = queue;
- goto out;
- }
-
- if (response->request.status.status_code >= IPP_OK_CONFLICT) {
- DEBUG(0,("Unable to get printer status for %s - %s\n", printername,
- ippErrorString(response->request.status.status_code)));
- *q = queue;
- goto out;
- }
-
- /*
- * Get the current printer status and convert it to the SAMBA values.
- */
-
- if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) {
- if (attr->values[0].integer == IPP_PRINTER_STOPPED)
- status->status = LPSTAT_STOPPED;
- else
- status->status = LPSTAT_OK;
- }
-
- if ((attr = ippFindAttribute(response, "printer-state-message",
- IPP_TAG_TEXT)) != NULL)
- fstrcpy(status->message, attr->values[0].string.text);
-
- if ((attr = ippFindAttribute(response, "printer-current-time",
- IPP_TAG_DATE)) != NULL)
- printer_current_time = ippDateToTime(attr->values[0].date);
-
- if ((attr = ippFindAttribute(response, "printer-up-time",
- IPP_TAG_INTEGER)) != NULL)
- printer_up_time = attr->values[0].integer;
-
- ippDelete(response);
- response = NULL;
-
- /*
- * Build an IPP_GET_JOBS request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * requested-attributes
- * printer-uri
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_GET_JOBS;
- request->request.op.request_id = 3;
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, "utf-8");
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
-
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
- "requested-attributes",
- (sizeof(jattrs) / sizeof(jattrs[0])),
- NULL, jattrs);
-
- /*
- * Do the request and get back a response...
- */
-
- slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", printername);
-
- if ((response = cupsDoRequest(http, request, httpPath)) == NULL) {
- DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
- ippErrorString(cupsLastError())));
- goto out;
- }
-
- if (response->request.status.status_code >= IPP_OK_CONFLICT) {
- DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
- ippErrorString(response->request.status.status_code)));
- goto out;
- }
-
- /*
- * Process the jobs...
- */
-
- qcount = 0;
- qalloc = 0;
- queue = NULL;
-
- for (attr = response->attrs; attr != NULL; attr = attr->next) {
- /*
- * Skip leading attributes until we hit a job...
- */
-
- while (attr != NULL && attr->group_tag != IPP_TAG_JOB)
- attr = attr->next;
-
- if (attr == NULL)
- break;
-
- /*
- * Allocate memory as needed...
- */
- if (qcount >= qalloc) {
- qalloc += 16;
-
- queue = SMB_REALLOC_ARRAY(queue, print_queue_struct, qalloc);
-
- if (queue == NULL) {
- DEBUG(0,("iprint_queue_get: Not enough memory!"));
- qcount = 0;
- goto out;
- }
- }
-
- temp = queue + qcount;
- memset(temp, 0, sizeof(print_queue_struct));
-
- /*
- * Pull the needed attributes from this job...
- */
-
- job_id = 0;
- job_priority = 50;
- job_status = IPP_JOB_PENDING;
- job_time = 0;
- job_k_octets = 0;
- user_name = NULL;
- job_name = NULL;
-
- while (attr != NULL && attr->group_tag == IPP_TAG_JOB) {
- if (attr->name == NULL) {
- attr = attr->next;
- break;
- }
-
- if (strcmp(attr->name, "job-id") == 0 &&
- attr->value_tag == IPP_TAG_INTEGER)
- job_id = attr->values[0].integer;
-
- if (strcmp(attr->name, "job-k-octets") == 0 &&
- attr->value_tag == IPP_TAG_INTEGER)
- job_k_octets = attr->values[0].integer;
-
- if (strcmp(attr->name, "job-priority") == 0 &&
- attr->value_tag == IPP_TAG_INTEGER)
- job_priority = attr->values[0].integer;
-
- if (strcmp(attr->name, "job-state") == 0 &&
- attr->value_tag == IPP_TAG_ENUM)
- job_status = (ipp_jstate_t)(attr->values[0].integer);
-
- if (strcmp(attr->name, "time-at-creation") == 0 &&
- attr->value_tag == IPP_TAG_INTEGER)
- {
- /*
- * If jobs times are in Unix time, the accuracy of the job
- * start time depends upon the iPrint server's time being
- * set correctly. Otherwise, the accuracy depends upon
- * the Samba server's time being set correctly
- */
-
- if (jobUseUnixTime)
- job_time = attr->values[0].integer;
- else
- job_time = time(NULL) - printer_up_time + attr->values[0].integer;
- }
-
- if (strcmp(attr->name, "job-name") == 0 &&
- (attr->value_tag == IPP_TAG_NAMELANG ||
- attr->value_tag == IPP_TAG_NAME))
- job_name = attr->values[0].string.text;
-
- if (strcmp(attr->name, "job-originating-user-name") == 0 &&
- (attr->value_tag == IPP_TAG_NAMELANG ||
- attr->value_tag == IPP_TAG_NAME))
- user_name = attr->values[0].string.text;
-
- attr = attr->next;
- }
-
- /*
- * See if we have everything needed...
- */
-
- if (user_name == NULL || job_name == NULL || job_id == 0) {
- if (attr == NULL)
- break;
- else
- continue;
- }
-
- temp->job = job_id;
- temp->size = job_k_octets * 1024;
- temp->status = job_status == IPP_JOB_PENDING ? LPQ_QUEUED :
- job_status == IPP_JOB_STOPPED ? LPQ_PAUSED :
- job_status == IPP_JOB_HELD ? LPQ_PAUSED :
- LPQ_PRINTING;
- temp->priority = job_priority;
- temp->time = job_time;
- strncpy(temp->fs_user, user_name, sizeof(temp->fs_user) - 1);
- strncpy(temp->fs_file, job_name, sizeof(temp->fs_file) - 1);
-
- qcount ++;
-
- if (attr == NULL)
- break;
- }
-
- /*
- * Return the job queue...
- */
-
- *q = queue;
-
- out:
- if (response)
- ippDelete(response);
-
- if (language)
- cupsLangFree(language);
-
- if (http)
- httpClose(http);
-
- return qcount;
-}
-
-
-/*
- * 'iprint_queue_pause()' - Pause a print queue.
- */
-
-static int iprint_queue_pause(int snum)
-{
- return(-1); /* Not supported without credentials */
-}
-
-
-/*
- * 'iprint_queue_resume()' - Restart a print queue.
- */
-
-static int iprint_queue_resume(int snum)
-{
- return(-1); /* Not supported without credentials */
-}
-
-/*******************************************************************
- * iPrint printing interface definitions...
- ******************************************************************/
-
-struct printif iprint_printif =
-{
- PRINT_IPRINT,
- iprint_queue_get,
- iprint_queue_pause,
- iprint_queue_resume,
- iprint_job_delete,
- iprint_job_pause,
- iprint_job_resume,
- iprint_job_submit,
-};
-
-#else
- /* this keeps fussy compilers happy */
- void print_iprint_dummy(void);
- void print_iprint_dummy(void) {}
-#endif /* HAVE_IPRINT */
+++ /dev/null
-/*
- * Copyright (C) 1997-1998 by Norm Jacobs, Colorado Springs, Colorado, USA
- * Copyright (C) 1997-1998 by Sun Microsystem, Inc.
- * All Rights Reserved
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
- */
-
-/*
- * This module implements support for gathering and comparing available
- * printer information on a SVID or XPG4 compliant system. It does this
- * through the use of the SVID/XPG4 command "lpstat(1)".
- *
- * The expectations is that execution of the command "lpstat -v" will
- * generate responses in the form of:
- *
- * device for serial: /dev/term/b
- * system for fax: server
- * system for color: server (as printer chroma)
- */
-
-
-#include "includes.h"
-
-#if defined(SYSV) || defined(HPUX)
-bool sysv_cache_reload(void)
-{
- char **lines;
- int i;
-
-#if defined(HPUX)
- DEBUG(5, ("reloading hpux printcap cache\n"));
-#else
- DEBUG(5, ("reloading sysv printcap cache\n"));
-#endif
-
- if ((lines = file_lines_pload("/usr/bin/lpstat -v", NULL)) == NULL)
- {
-#if defined(HPUX)
-
- /*
- * if "lpstat -v" is NULL then we check if schedular is running if it is
- * that means no printers are added on the HP-UX system, if schedular is not
- * running we display reload error.
- */
-
- char **scheduler;
- scheduler = file_lines_pload("/usr/bin/lpstat -r", NULL);
- if(!strcmp(*scheduler,"scheduler is running")){
- DEBUG(3,("No Printers found!!!\n"));
- TALLOC_FREE(scheduler);
- return True;
- }
- else{
- DEBUG(3,("Scheduler is not running!!!\n"));
- TALLOC_FREE(scheduler);
- return False;
- }
-#else
- DEBUG(3,("No Printers found!!!\n"));
- return False;
-#endif
- }
-
- for (i = 0; lines[i]; i++) {
- char *name, *tmp;
- char *buf = lines[i];
-
- /* eat "system/device for " */
- if (((tmp = strchr_m(buf, ' ')) == NULL) ||
- ((tmp = strchr_m(++tmp, ' ')) == NULL))
- continue;
-
- /*
- * In case we're only at the "for ".
- */
-
- if(!strncmp("for ", ++tmp, 4)) {
- tmp=strchr_m(tmp, ' ');
- tmp++;
- }
-
- /* Eat whitespace. */
-
- while(*tmp == ' ')
- ++tmp;
-
- /*
- * On HPUX there is an extra line that can be ignored.
- * d.thibadeau 2001/08/09
- */
- if(!strncmp("remote to", tmp, 9))
- continue;
-
- name = tmp;
-
- /* truncate the ": ..." */
- if ((tmp = strchr_m(name, ':')) != NULL)
- *tmp = '\0';
-
- /* add it to the cache */
- if (!pcap_cache_add(name, NULL)) {
- TALLOC_FREE(lines);
- return False;
- }
- }
-
- TALLOC_FREE(lines);
- return True;
-}
-
-#else
-/* this keeps fussy compilers happy */
- void print_svid_dummy(void);
- void print_svid_dummy(void) {}
-#endif
+++ /dev/null
-/*
- Unix SMB/CIFS implementation.
- printing backend routines for smbd - using files_struct rather
- than only snum
- Copyright (C) Andrew Tridgell 1992-2000
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-
-/***************************************************************************
-open a print file and setup a fsp for it. This is a wrapper around
-print_job_start().
-***************************************************************************/
-
-NTSTATUS print_fsp_open(struct smb_request *req, connection_struct *conn,
- const char *fname,
- uint16_t current_vuid, files_struct *fsp)
-{
- int jobid;
- fstring name;
- NTSTATUS status;
-
- fstrcpy( name, "Remote Downlevel Document");
- if (fname) {
- const char *p = strrchr(fname, '/');
- fstrcat(name, " ");
- if (!p) {
- p = fname;
- }
- fstrcat(name, p);
- }
-
- jobid = print_job_start(conn->server_info, SNUM(conn), name, NULL);
- if (jobid == -1) {
- status = map_nt_error_from_unix(errno);
- return status;
- }
-
- /* Convert to RAP id. */
- fsp->rap_print_jobid = pjobid_to_rap(lp_const_servicename(SNUM(conn)), jobid);
- if (fsp->rap_print_jobid == 0) {
- /* We need to delete the entry in the tdb. */
- pjob_delete(lp_const_servicename(SNUM(conn)), jobid);
- return NT_STATUS_ACCESS_DENIED; /* No errno around here */
- }
-
- status = create_synthetic_smb_fname(fsp,
- print_job_fname(lp_const_servicename(SNUM(conn)), jobid), NULL,
- NULL, &fsp->fsp_name);
- if (!NT_STATUS_IS_OK(status)) {
- pjob_delete(lp_const_servicename(SNUM(conn)), jobid);
- return status;
- }
- /* setup a full fsp */
- fsp->fh->fd = print_job_fd(lp_const_servicename(SNUM(conn)),jobid);
- GetTimeOfDay(&fsp->open_time);
- fsp->vuid = current_vuid;
- fsp->fh->pos = -1;
- fsp->can_lock = True;
- fsp->can_read = False;
- fsp->access_mask = FILE_GENERIC_WRITE;
- fsp->can_write = True;
- fsp->print_file = True;
- fsp->modified = False;
- fsp->oplock_type = NO_OPLOCK;
- fsp->sent_oplock_break = NO_BREAK_SENT;
- fsp->is_directory = False;
- fsp->wcp = NULL;
- SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
- fsp->mode = fsp->fsp_name->st.st_ex_mode;
- fsp->file_id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
-
- return NT_STATUS_OK;
-}
-
-/****************************************************************************
- Print a file - called on closing the file.
-****************************************************************************/
-
-void print_fsp_end(files_struct *fsp, enum file_close_type close_type)
-{
- uint32 jobid;
-
- if (fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DELETE_ON_CLOSE) {
- /*
- * Truncate the job. print_job_end will take
- * care of deleting it for us. JRA.
- */
- sys_ftruncate(fsp->fh->fd, 0);
- }
-
- if (fsp->fsp_name) {
- TALLOC_FREE(fsp->fsp_name);
- }
-
- if (!rap_to_pjobid(fsp->rap_print_jobid, NULL, &jobid)) {
- DEBUG(3,("print_fsp_end: Unable to convert RAP jobid %u to print jobid.\n",
- (unsigned int)fsp->rap_print_jobid ));
- return;
- }
-
- print_job_end(SNUM(fsp->conn),jobid, close_type);
-}
-
-/****************************************************************************
- Discovered by Sebastian Kloska <oncaphillis@snafu.de>. When print files
- go beyond 4GB, the 32-bit offset sent in old SMBwrite calls is relative
- to the current 4GB chunk we're writing to.
-****************************************************************************/
-
-SMB_OFF_T printfile_offset(files_struct *fsp, SMB_OFF_T offset)
-{
- SMB_STRUCT_STAT st;
-
- if (sys_fstat(fsp->fh->fd, &st, false) == -1) {
- DEBUG(3,("printfile_offset: sys_fstat failed on %s (%s)\n",
- fsp_str_dbg(fsp),
- strerror(errno) ));
- return offset;
- }
-
- return (st.st_ex_size & 0xffffffff00000000LL) + offset;
-}
+++ /dev/null
-/*
- Unix SMB/Netbios implementation.
- Version 3.0
- printing backend routines
- Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) Jeremy Allison 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 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "printing.h"
-
-extern struct current_user current_user;
-extern userdom_struct current_user_info;
-
-/* Current printer interface */
-static bool remove_from_jobs_changed(const char* sharename, uint32 jobid);
-
-/*
- the printing backend revolves around a tdb database that stores the
- SMB view of the print queue
-
- The key for this database is a jobid - a internally generated number that
- uniquely identifies a print job
-
- reading the print queue involves two steps:
- - possibly running lpq and updating the internal database from that
- - reading entries from the database
-
- jobids are assigned when a job starts spooling.
-*/
-
-static TDB_CONTEXT *rap_tdb;
-static uint16 next_rap_jobid;
-struct rap_jobid_key {
- fstring sharename;
- uint32 jobid;
-};
-
-/***************************************************************************
- Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
- bit RPC jobids.... JRA.
-***************************************************************************/
-
-uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
-{
- uint16 rap_jobid;
- TDB_DATA data, key;
- struct rap_jobid_key jinfo;
- uint8 buf[2];
-
- DEBUG(10,("pjobid_to_rap: called.\n"));
-
- if (!rap_tdb) {
- /* Create the in-memory tdb. */
- rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
- if (!rap_tdb)
- return 0;
- }
-
- ZERO_STRUCT( jinfo );
- fstrcpy( jinfo.sharename, sharename );
- jinfo.jobid = jobid;
- key.dptr = (uint8 *)&jinfo;
- key.dsize = sizeof(jinfo);
-
- data = tdb_fetch(rap_tdb, key);
- if (data.dptr && data.dsize == sizeof(uint16)) {
- rap_jobid = SVAL(data.dptr, 0);
- SAFE_FREE(data.dptr);
- DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
- (unsigned int)jobid, (unsigned int)rap_jobid));
- return rap_jobid;
- }
- SAFE_FREE(data.dptr);
- /* Not found - create and store mapping. */
- rap_jobid = ++next_rap_jobid;
- if (rap_jobid == 0)
- rap_jobid = ++next_rap_jobid;
- SSVAL(buf,0,rap_jobid);
- data.dptr = buf;
- data.dsize = sizeof(rap_jobid);
- tdb_store(rap_tdb, key, data, TDB_REPLACE);
- tdb_store(rap_tdb, data, key, TDB_REPLACE);
-
- DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
- (unsigned int)jobid, (unsigned int)rap_jobid));
- return rap_jobid;
-}
-
-bool rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
-{
- TDB_DATA data, key;
- uint8 buf[2];
-
- DEBUG(10,("rap_to_pjobid called.\n"));
-
- if (!rap_tdb)
- return False;
-
- SSVAL(buf,0,rap_jobid);
- key.dptr = buf;
- key.dsize = sizeof(rap_jobid);
- data = tdb_fetch(rap_tdb, key);
- if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) )
- {
- struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
- if (sharename != NULL) {
- fstrcpy( sharename, jinfo->sharename );
- }
- *pjobid = jinfo->jobid;
- DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
- (unsigned int)*pjobid, (unsigned int)rap_jobid));
- SAFE_FREE(data.dptr);
- return True;
- }
-
- DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
- (unsigned int)rap_jobid));
- SAFE_FREE(data.dptr);
- return False;
-}
-
-static void rap_jobid_delete(const char* sharename, uint32 jobid)
-{
- TDB_DATA key, data;
- uint16 rap_jobid;
- struct rap_jobid_key jinfo;
- uint8 buf[2];
-
- DEBUG(10,("rap_jobid_delete: called.\n"));
-
- if (!rap_tdb)
- return;
-
- ZERO_STRUCT( jinfo );
- fstrcpy( jinfo.sharename, sharename );
- jinfo.jobid = jobid;
- key.dptr = (uint8 *)&jinfo;
- key.dsize = sizeof(jinfo);
-
- data = tdb_fetch(rap_tdb, key);
- if (!data.dptr || (data.dsize != sizeof(uint16))) {
- DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
- (unsigned int)jobid ));
- SAFE_FREE(data.dptr);
- return;
- }
-
- DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
- (unsigned int)jobid ));
-
- rap_jobid = SVAL(data.dptr, 0);
- SAFE_FREE(data.dptr);
- SSVAL(buf,0,rap_jobid);
- data.dptr = buf;
- data.dsize = sizeof(rap_jobid);
- tdb_delete(rap_tdb, key);
- tdb_delete(rap_tdb, data);
-}
-
-static int get_queue_status(const char* sharename, print_status_struct *);
-
-/****************************************************************************
- Initialise the printing backend. Called once at startup before the fork().
-****************************************************************************/
-
-bool print_backend_init(struct messaging_context *msg_ctx)
-{
- const char *sversion = "INFO/version";
- int services = lp_numservices();
- int snum;
-
- unlink(cache_path("printing.tdb"));
- mkdir(cache_path("printing"),0755);
-
- /* handle a Samba upgrade */
-
- for (snum = 0; snum < services; snum++) {
- struct tdb_print_db *pdb;
- if (!lp_print_ok(snum))
- continue;
-
- pdb = get_print_db_byname(lp_const_servicename(snum));
- if (!pdb)
- continue;
- if (tdb_lock_bystring(pdb->tdb, sversion) == -1) {
- DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
- release_print_db(pdb);
- return False;
- }
- if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
- tdb_wipe_all(pdb->tdb);
- tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
- }
- tdb_unlock_bystring(pdb->tdb, sversion);
- release_print_db(pdb);
- }
-
- close_all_print_db(); /* Don't leave any open. */
-
- /* do NT print initialization... */
- return nt_printing_init(msg_ctx);
-}
-
-/****************************************************************************
- Shut down printing backend. Called once at shutdown to close the tdb.
-****************************************************************************/
-
-void printing_end(void)
-{
- close_all_print_db(); /* Don't leave any open. */
-}
-
-/****************************************************************************
- Retrieve the set of printing functions for a given service. This allows
- us to set the printer function table based on the value of the 'printing'
- service parameter.
-
- Use the generic interface as the default and only use cups interface only
- when asked for (and only when supported)
-****************************************************************************/
-
-static struct printif *get_printer_fns_from_type( enum printing_types type )
-{
- struct printif *printer_fns = &generic_printif;
-
-#ifdef HAVE_CUPS
- if ( type == PRINT_CUPS ) {
- printer_fns = &cups_printif;
- }
-#endif /* HAVE_CUPS */
-
-#ifdef HAVE_IPRINT
- if ( type == PRINT_IPRINT ) {
- printer_fns = &iprint_printif;
- }
-#endif /* HAVE_IPRINT */
-
- printer_fns->type = type;
-
- return printer_fns;
-}
-
-static struct printif *get_printer_fns( int snum )
-{
- return get_printer_fns_from_type( (enum printing_types)lp_printing(snum) );
-}
-
-
-/****************************************************************************
- Useful function to generate a tdb key.
-****************************************************************************/
-
-static TDB_DATA print_key(uint32 jobid, uint32 *tmp)
-{
- TDB_DATA ret;
-
- SIVAL(tmp, 0, jobid);
- ret.dptr = (uint8 *)tmp;
- ret.dsize = sizeof(*tmp);
- return ret;
-}
-
-/***********************************************************************
- unpack a pjob from a tdb buffer
-***********************************************************************/
-
-int unpack_pjob( uint8 *buf, int buflen, struct printjob *pjob )
-{
- int len = 0;
- int used;
- uint32 pjpid, pjsysjob, pjfd, pjstarttime, pjstatus;
- uint32 pjsize, pjpage_count, pjspooled, pjsmbjob;
-
- if ( !buf || !pjob )
- return -1;
-
- len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
- &pjpid,
- &pjsysjob,
- &pjfd,
- &pjstarttime,
- &pjstatus,
- &pjsize,
- &pjpage_count,
- &pjspooled,
- &pjsmbjob,
- pjob->filename,
- pjob->jobname,
- pjob->user,
- pjob->queuename);
-
- if ( len == -1 )
- return -1;
-
- if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
- return -1;
-
- len += used;
-
- pjob->pid = pjpid;
- pjob->sysjob = pjsysjob;
- pjob->fd = pjfd;
- pjob->starttime = pjstarttime;
- pjob->status = pjstatus;
- pjob->size = pjsize;
- pjob->page_count = pjpage_count;
- pjob->spooled = pjspooled;
- pjob->smbjob = pjsmbjob;
-
- return len;
-
-}
-
-/****************************************************************************
- Useful function to find a print job in the database.
-****************************************************************************/
-
-static struct printjob *print_job_find(const char *sharename, uint32 jobid)
-{
- static struct printjob pjob;
- uint32_t tmp;
- TDB_DATA ret;
- struct tdb_print_db *pdb = get_print_db_byname(sharename);
-
- DEBUG(10,("print_job_find: looking up job %u for share %s\n",
- (unsigned int)jobid, sharename ));
-
- if (!pdb) {
- return NULL;
- }
-
- ret = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
- release_print_db(pdb);
-
- if (!ret.dptr) {
- DEBUG(10,("print_job_find: failed to find jobid %u.\n", (unsigned int)jobid ));
- return NULL;
- }
-
- if ( pjob.nt_devmode ) {
- free_nt_devicemode( &pjob.nt_devmode );
- }
-
- ZERO_STRUCT( pjob );
-
- if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
- DEBUG(10,("print_job_find: failed to unpack jobid %u.\n", (unsigned int)jobid ));
- SAFE_FREE(ret.dptr);
- return NULL;
- }
-
- SAFE_FREE(ret.dptr);
-
- DEBUG(10,("print_job_find: returning system job %d for jobid %u.\n",
- (int)pjob.sysjob, (unsigned int)jobid ));
-
- return &pjob;
-}
-
-/* Convert a unix jobid to a smb jobid */
-
-struct unixjob_traverse_state {
- int sysjob;
- uint32 sysjob_to_jobid_value;
-};
-
-static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
- TDB_DATA data, void *private_data)
-{
- struct printjob *pjob;
- struct unixjob_traverse_state *state =
- (struct unixjob_traverse_state *)private_data;
-
- if (!data.dptr || data.dsize == 0)
- return 0;
-
- pjob = (struct printjob *)data.dptr;
- if (key.dsize != sizeof(uint32))
- return 0;
-
- if (state->sysjob == pjob->sysjob) {
- uint32 jobid = IVAL(key.dptr,0);
-
- state->sysjob_to_jobid_value = jobid;
- return 1;
- }
-
- return 0;
-}
-
-/****************************************************************************
- This is a *horribly expensive call as we have to iterate through all the
- current printer tdb's. Don't do this often ! JRA.
-****************************************************************************/
-
-uint32 sysjob_to_jobid(int unix_jobid)
-{
- int services = lp_numservices();
- int snum;
- struct unixjob_traverse_state state;
-
- state.sysjob = unix_jobid;
- state.sysjob_to_jobid_value = (uint32)-1;
-
- for (snum = 0; snum < services; snum++) {
- struct tdb_print_db *pdb;
- if (!lp_print_ok(snum))
- continue;
- pdb = get_print_db_byname(lp_const_servicename(snum));
- if (!pdb) {
- continue;
- }
- tdb_traverse(pdb->tdb, unixjob_traverse_fn, &state);
- release_print_db(pdb);
- if (state.sysjob_to_jobid_value != (uint32)-1)
- return state.sysjob_to_jobid_value;
- }
- return (uint32)-1;
-}
-
-/****************************************************************************
- Send notifications based on what has changed after a pjob_store.
-****************************************************************************/
-
-static const struct {
- uint32 lpq_status;
- uint32 spoolss_status;
-} lpq_to_spoolss_status_map[] = {
- { LPQ_QUEUED, JOB_STATUS_QUEUED },
- { LPQ_PAUSED, JOB_STATUS_PAUSED },
- { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
- { LPQ_PRINTING, JOB_STATUS_PRINTING },
- { LPQ_DELETING, JOB_STATUS_DELETING },
- { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
- { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
- { LPQ_PRINTED, JOB_STATUS_PRINTED },
- { LPQ_DELETED, JOB_STATUS_DELETED },
- { LPQ_BLOCKED, JOB_STATUS_BLOCKED_DEVQ },
- { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
- { -1, 0 }
-};
-
-/* Convert a lpq status value stored in printing.tdb into the
- appropriate win32 API constant. */
-
-static uint32 map_to_spoolss_status(uint32 lpq_status)
-{
- int i = 0;
-
- while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
- if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
- return lpq_to_spoolss_status_map[i].spoolss_status;
- i++;
- }
-
- return 0;
-}
-
-static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data,
- struct printjob *new_data)
-{
- bool new_job = False;
-
- if (!old_data)
- new_job = True;
-
- /* Job attributes that can't be changed. We only send
- notification for these on a new job. */
-
- /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the
- NOTIFY_INFO_DATA buffer, we *have* to send the job submission
- time first or else we'll end up with potential alignment
- errors. I don't think the systemtime should be spooled as
- a string, but this gets us around that error.
- --jerry (i'll feel dirty for this) */
-
- if (new_job) {
- notify_job_submitted(sharename, jobid, new_data->starttime);
- notify_job_username(sharename, jobid, new_data->user);
- }
-
- if (new_job || !strequal(old_data->jobname, new_data->jobname))
- notify_job_name(sharename, jobid, new_data->jobname);
-
- /* Job attributes of a new job or attributes that can be
- modified. */
-
- if (new_job || !strequal(old_data->jobname, new_data->jobname))
- notify_job_name(sharename, jobid, new_data->jobname);
-
- if (new_job || old_data->status != new_data->status)
- notify_job_status(sharename, jobid, map_to_spoolss_status(new_data->status));
-
- if (new_job || old_data->size != new_data->size)
- notify_job_total_bytes(sharename, jobid, new_data->size);
-
- if (new_job || old_data->page_count != new_data->page_count)
- notify_job_total_pages(sharename, jobid, new_data->page_count);
-}
-
-/****************************************************************************
- Store a job structure back to the database.
-****************************************************************************/
-
-static bool pjob_store(const char* sharename, uint32 jobid, struct printjob *pjob)
-{
- uint32_t tmp;
- TDB_DATA old_data, new_data;
- bool ret = False;
- struct tdb_print_db *pdb = get_print_db_byname(sharename);
- uint8 *buf = NULL;
- int len, newlen, buflen;
-
-
- if (!pdb)
- return False;
-
- /* Get old data */
-
- old_data = tdb_fetch(pdb->tdb, print_key(jobid, &tmp));
-
- /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
-
- newlen = 0;
-
- do {
- len = 0;
- buflen = newlen;
- len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
- (uint32)pjob->pid,
- (uint32)pjob->sysjob,
- (uint32)pjob->fd,
- (uint32)pjob->starttime,
- (uint32)pjob->status,
- (uint32)pjob->size,
- (uint32)pjob->page_count,
- (uint32)pjob->spooled,
- (uint32)pjob->smbjob,
- pjob->filename,
- pjob->jobname,
- pjob->user,
- pjob->queuename);
-
- len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
-
- if (buflen != len) {
- buf = (uint8 *)SMB_REALLOC(buf, len);
- if (!buf) {
- DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
- goto done;
- }
- newlen = len;
- }
- } while ( buflen != len );
-
-
- /* Store new data */
-
- new_data.dptr = buf;
- new_data.dsize = len;
- ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data,
- TDB_REPLACE) == 0);
-
- release_print_db(pdb);
-
- /* Send notify updates for what has changed */
-
- if ( ret ) {
- struct printjob old_pjob;
-
- if ( old_data.dsize )
- {
- if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
- {
- pjob_store_notify( sharename, jobid, &old_pjob , pjob );
- free_nt_devicemode( &old_pjob.nt_devmode );
- }
- }
- else {
- /* new job */
- pjob_store_notify( sharename, jobid, NULL, pjob );
- }
- }
-
-done:
- SAFE_FREE( old_data.dptr );
- SAFE_FREE( buf );
-
- return ret;
-}
-
-/****************************************************************************
- Remove a job structure from the database.
-****************************************************************************/
-
-void pjob_delete(const char* sharename, uint32 jobid)
-{
- uint32_t tmp;
- struct printjob *pjob;
- uint32 job_status = 0;
- struct tdb_print_db *pdb;
-
- pdb = get_print_db_byname( sharename );
-
- if (!pdb)
- return;
-
- pjob = print_job_find( sharename, jobid );
-
- if (!pjob) {
- DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
- (unsigned int)jobid));
- release_print_db(pdb);
- return;
- }
-
- /* We must cycle through JOB_STATUS_DELETING and
- JOB_STATUS_DELETED for the port monitor to delete the job
- properly. */
-
- job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
- notify_job_status(sharename, jobid, job_status);
-
- /* Remove from printing.tdb */
-
- tdb_delete(pdb->tdb, print_key(jobid, &tmp));
- remove_from_jobs_changed(sharename, jobid);
- release_print_db( pdb );
- rap_jobid_delete(sharename, jobid);
-}
-
-/****************************************************************************
- List a unix job in the print database.
-****************************************************************************/
-
-static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid)
-{
- struct printjob pj, *old_pj;
-
- if (jobid == (uint32)-1)
- jobid = q->job + UNIX_JOB_START;
-
- /* Preserve the timestamp on an existing unix print job */
-
- old_pj = print_job_find(sharename, jobid);
-
- ZERO_STRUCT(pj);
-
- pj.pid = (pid_t)-1;
- pj.sysjob = q->job;
- pj.fd = -1;
- pj.starttime = old_pj ? old_pj->starttime : q->time;
- pj.status = q->status;
- pj.size = q->size;
- pj.spooled = True;
- fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
- if (jobid < UNIX_JOB_START) {
- pj.smbjob = True;
- fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
- } else {
- pj.smbjob = False;
- fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
- }
- fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
- fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
-
- pjob_store(sharename, jobid, &pj);
-}
-
-
-struct traverse_struct {
- print_queue_struct *queue;
- int qcount, snum, maxcount, total_jobs;
- const char *sharename;
- time_t lpq_time;
- const char *lprm_command;
- struct printif *print_if;
-};
-
-/****************************************************************************
- Utility fn to delete any jobs that are no longer active.
-****************************************************************************/
-
-static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
-{
- struct traverse_struct *ts = (struct traverse_struct *)state;
- struct printjob pjob;
- uint32 jobid;
- int i = 0;
-
- if ( key.dsize != sizeof(jobid) )
- return 0;
-
- jobid = IVAL(key.dptr, 0);
- if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
- return 0;
- free_nt_devicemode( &pjob.nt_devmode );
-
-
- if (!pjob.smbjob) {
- /* remove a unix job if it isn't in the system queue any more */
-
- for (i=0;i<ts->qcount;i++) {
- uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
- if (jobid == u_jobid)
- break;
- }
- if (i == ts->qcount) {
- DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
- (unsigned int)jobid ));
- pjob_delete(ts->sharename, jobid);
- return 0;
- }
-
- /* need to continue the the bottom of the function to
- save the correct attributes */
- }
-
- /* maybe it hasn't been spooled yet */
- if (!pjob.spooled) {
- /* if a job is not spooled and the process doesn't
- exist then kill it. This cleans up after smbd
- deaths */
- if (!process_exists_by_pid(pjob.pid)) {
- DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
- (unsigned int)jobid, (unsigned int)pjob.pid ));
- pjob_delete(ts->sharename, jobid);
- } else
- ts->total_jobs++;
- return 0;
- }
-
- /* this check only makes sense for jobs submitted from Windows clients */
-
- if ( pjob.smbjob ) {
- for (i=0;i<ts->qcount;i++) {
- uint32 curr_jobid;
-
- if ( pjob.status == LPQ_DELETED )
- continue;
-
- curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
-
- if (jobid == curr_jobid) {
-
- /* try to clean up any jobs that need to be deleted */
-
- if ( pjob.status == LPQ_DELETING ) {
- int result;
-
- result = (*(ts->print_if->job_delete))(
- ts->sharename, ts->lprm_command, &pjob );
-
- if ( result != 0 ) {
- /* if we can't delete, then reset the job status */
- pjob.status = LPQ_QUEUED;
- pjob_store(ts->sharename, jobid, &pjob);
- }
- else {
- /* if we deleted the job, the remove the tdb record */
- pjob_delete(ts->sharename, jobid);
- pjob.status = LPQ_DELETED;
- }
-
- }
-
- break;
- }
- }
- }
-
- /* The job isn't in the system queue - we have to assume it has
- completed, so delete the database entry. */
-
- if (i == ts->qcount) {
-
- /* A race can occur between the time a job is spooled and
- when it appears in the lpq output. This happens when
- the job is added to printing.tdb when another smbd
- running print_queue_update() has completed a lpq and
- is currently traversing the printing tdb and deleting jobs.
- Don't delete the job if it was submitted after the lpq_time. */
-
- if (pjob.starttime < ts->lpq_time) {
- DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
- (unsigned int)jobid,
- (unsigned int)pjob.starttime,
- (unsigned int)ts->lpq_time ));
- pjob_delete(ts->sharename, jobid);
- } else
- ts->total_jobs++;
- return 0;
- }
-
- /* Save the pjob attributes we will store.
- FIXME!!! This is the only place where queue->job
- represents the SMB jobid --jerry */
-
- ts->queue[i].job = jobid;
- ts->queue[i].size = pjob.size;
- ts->queue[i].page_count = pjob.page_count;
- ts->queue[i].status = pjob.status;
- ts->queue[i].priority = 1;
- ts->queue[i].time = pjob.starttime;
- fstrcpy(ts->queue[i].fs_user, pjob.user);
- fstrcpy(ts->queue[i].fs_file, pjob.jobname);
-
- ts->total_jobs++;
-
- return 0;
-}
-
-/****************************************************************************
- Check if the print queue has been updated recently enough.
-****************************************************************************/
-
-static void print_cache_flush(const char *sharename)
-{
- fstring key;
- struct tdb_print_db *pdb = get_print_db_byname(sharename);
-
- if (!pdb)
- return;
- slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
- tdb_store_int32(pdb->tdb, key, -1);
- release_print_db(pdb);
-}
-
-/****************************************************************************
- Check if someone already thinks they are doing the update.
-****************************************************************************/
-
-static pid_t get_updating_pid(const char *sharename)
-{
- fstring keystr;
- TDB_DATA data, key;
- pid_t updating_pid;
- struct tdb_print_db *pdb = get_print_db_byname(sharename);
-
- if (!pdb)
- return (pid_t)-1;
- slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
- key = string_tdb_data(keystr);
-
- data = tdb_fetch(pdb->tdb, key);
- release_print_db(pdb);
- if (!data.dptr || data.dsize != sizeof(pid_t)) {
- SAFE_FREE(data.dptr);
- return (pid_t)-1;
- }
-
- updating_pid = IVAL(data.dptr, 0);
- SAFE_FREE(data.dptr);
-
- if (process_exists_by_pid(updating_pid))
- return updating_pid;
-
- return (pid_t)-1;
-}
-
-/****************************************************************************
- Set the fact that we're doing the update, or have finished doing the update
- in the tdb.
-****************************************************************************/
-
-static void set_updating_pid(const fstring sharename, bool updating)
-{
- fstring keystr;
- TDB_DATA key;
- TDB_DATA data;
- pid_t updating_pid = sys_getpid();
- uint8 buffer[4];
-
- struct tdb_print_db *pdb = get_print_db_byname(sharename);
-
- if (!pdb)
- return;
-
- slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
- key = string_tdb_data(keystr);
-
- DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
- updating ? "" : "not ",
- sharename ));
-
- if ( !updating ) {
- tdb_delete(pdb->tdb, key);
- release_print_db(pdb);
- return;
- }
-
- SIVAL( buffer, 0, updating_pid);
- data.dptr = buffer;
- data.dsize = 4; /* we always assume this is a 4 byte value */
-
- tdb_store(pdb->tdb, key, data, TDB_REPLACE);
- release_print_db(pdb);
-}
-
-/****************************************************************************
- Sort print jobs by submittal time.
-****************************************************************************/
-
-static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
-{
- /* Silly cases */
-
- if (!j1 && !j2)
- return 0;
- if (!j1)
- return -1;
- if (!j2)
- return 1;
-
- /* Sort on job start time */
-
- if (j1->time == j2->time)
- return 0;
- return (j1->time > j2->time) ? 1 : -1;
-}
-
-/****************************************************************************
- Store the sorted queue representation for later portmon retrieval.
- Skip deleted jobs
-****************************************************************************/
-
-static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
-{
- TDB_DATA data;
- int max_reported_jobs = lp_max_reported_jobs(pts->snum);
- print_queue_struct *queue = pts->queue;
- size_t len;
- size_t i;
- unsigned int qcount;
-
- if (max_reported_jobs && (max_reported_jobs < pts->qcount))
- pts->qcount = max_reported_jobs;
- qcount = 0;
-
- /* Work out the size. */
- data.dsize = 0;
- data.dsize += tdb_pack(NULL, 0, "d", qcount);
-
- for (i = 0; i < pts->qcount; i++) {
- if ( queue[i].status == LPQ_DELETED )
- continue;
-
- qcount++;
- data.dsize += tdb_pack(NULL, 0, "ddddddff",
- (uint32)queue[i].job,
- (uint32)queue[i].size,
- (uint32)queue[i].page_count,
- (uint32)queue[i].status,
- (uint32)queue[i].priority,
- (uint32)queue[i].time,
- queue[i].fs_user,
- queue[i].fs_file);
- }
-
- if ((data.dptr = (uint8 *)SMB_MALLOC(data.dsize)) == NULL)
- return;
-
- len = 0;
- len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
- for (i = 0; i < pts->qcount; i++) {
- if ( queue[i].status == LPQ_DELETED )
- continue;
-
- len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
- (uint32)queue[i].job,
- (uint32)queue[i].size,
- (uint32)queue[i].page_count,
- (uint32)queue[i].status,
- (uint32)queue[i].priority,
- (uint32)queue[i].time,
- queue[i].fs_user,
- queue[i].fs_file);
- }
-
- tdb_store(pdb->tdb, string_tdb_data("INFO/linear_queue_array"), data,
- TDB_REPLACE);
- SAFE_FREE(data.dptr);
- return;
-}
-
-static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
-{
- TDB_DATA data;
-
- ZERO_STRUCT(data);
-
- data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
- if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
- SAFE_FREE(data.dptr);
- ZERO_STRUCT(data);
- }
-
- return data;
-}
-
-static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
-{
- unsigned int i;
- unsigned int job_count = data.dsize / 4;
-
- for (i = 0; i < job_count; i++) {
- uint32 ch_jobid;
-
- ch_jobid = IVAL(data.dptr, i*4);
- if (ch_jobid == jobid)
- remove_from_jobs_changed(sharename, jobid);
- }
-}
-
-/****************************************************************************
- Check if the print queue has been updated recently enough.
-****************************************************************************/
-
-static bool print_cache_expired(const char *sharename, bool check_pending)
-{
- fstring key;
- time_t last_qscan_time, time_now = time(NULL);
- struct tdb_print_db *pdb = get_print_db_byname(sharename);
- bool result = False;
-
- if (!pdb)
- return False;
-
- snprintf(key, sizeof(key), "CACHE/%s", sharename);
- last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
-
- /*
- * Invalidate the queue for 3 reasons.
- * (1). last queue scan time == -1.
- * (2). Current time - last queue scan time > allowed cache time.
- * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
- * This last test picks up machines for which the clock has been moved
- * forward, an lpq scan done and then the clock moved back. Otherwise
- * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
- */
-
- if (last_qscan_time == ((time_t)-1)
- || (time_now - last_qscan_time) >= lp_lpqcachetime()
- || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
- {
- uint32 u;
- time_t msg_pending_time;
-
- DEBUG(4, ("print_cache_expired: cache expired for queue %s "
- "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
- sharename, (int)last_qscan_time, (int)time_now,
- (int)lp_lpqcachetime() ));
-
- /* check if another smbd has already sent a message to update the
- queue. Give the pending message one minute to clear and
- then send another message anyways. Make sure to check for
- clocks that have been run forward and then back again. */
-
- snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
-
- if ( check_pending
- && tdb_fetch_uint32( pdb->tdb, key, &u )
- && (msg_pending_time=u) > 0
- && msg_pending_time <= time_now
- && (time_now - msg_pending_time) < 60 )
- {
- DEBUG(4,("print_cache_expired: message already pending for %s. Accepting cache\n",
- sharename));
- goto done;
- }
-
- result = True;
- }
-
-done:
- release_print_db(pdb);
- return result;
-}
-
-/****************************************************************************
- main work for updating the lpq cahe for a printer queue
-****************************************************************************/
-
-static void print_queue_update_internal( const char *sharename,
- struct printif *current_printif,
- char *lpq_command, char *lprm_command )
-{
- int i, qcount;
- print_queue_struct *queue = NULL;
- print_status_struct status;
- print_status_struct old_status;
- struct printjob *pjob;
- struct traverse_struct tstruct;
- TDB_DATA data, key;
- TDB_DATA jcdata;
- fstring keystr, cachestr;
- struct tdb_print_db *pdb = get_print_db_byname(sharename);
-
- if (!pdb) {
- return;
- }
-
- DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
- sharename, current_printif->type, lpq_command));
-
- /*
- * Update the cache time FIRST ! Stops others even
- * attempting to get the lock and doing this
- * if the lpq takes a long time.
- */
-
- slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
- tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
-
- /* get the current queue using the appropriate interface */
- ZERO_STRUCT(status);
-
- qcount = (*(current_printif->queue_get))(sharename,
- current_printif->type,
- lpq_command, &queue, &status);
-
- DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
- qcount, (qcount != 1) ? "s" : "", sharename));
-
- /* Sort the queue by submission time otherwise they are displayed
- in hash order. */
-
- TYPESAFE_QSORT(queue, qcount, printjob_comp);
-
- /*
- any job in the internal database that is marked as spooled
- and doesn't exist in the system queue is considered finished
- and removed from the database
-
- any job in the system database but not in the internal database
- is added as a unix job
-
- fill in any system job numbers as we go
- */
-
- jcdata = get_jobs_changed_data(pdb);
-
- for (i=0; i<qcount; i++) {
- uint32 jobid = print_parse_jobid(queue[i].fs_file);
-
- if (jobid == (uint32)-1) {
- /* assume its a unix print job */
- print_unix_job(sharename, &queue[i], jobid);
- continue;
- }
-
- /* we have an active SMB print job - update its status */
- pjob = print_job_find(sharename, jobid);
- if (!pjob) {
- /* err, somethings wrong. Probably smbd was restarted
- with jobs in the queue. All we can do is treat them
- like unix jobs. Pity. */
- print_unix_job(sharename, &queue[i], jobid);
- continue;
- }
-
- pjob->sysjob = queue[i].job;
-
- /* don't reset the status on jobs to be deleted */
-
- if ( pjob->status != LPQ_DELETING )
- pjob->status = queue[i].status;
-
- pjob_store(sharename, jobid, pjob);
-
- check_job_changed(sharename, jcdata, jobid);
- }
-
- SAFE_FREE(jcdata.dptr);
-
- /* now delete any queued entries that don't appear in the
- system queue */
- tstruct.queue = queue;
- tstruct.qcount = qcount;
- tstruct.snum = -1;
- tstruct.total_jobs = 0;
- tstruct.lpq_time = time(NULL);
- tstruct.sharename = sharename;
- tstruct.lprm_command = lprm_command;
- tstruct.print_if = current_printif;
-
- tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
-
- /* Store the linearised queue, max jobs only. */
- store_queue_struct(pdb, &tstruct);
-
- SAFE_FREE(tstruct.queue);
-
- DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
- sharename, tstruct.total_jobs ));
-
- tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
-
- get_queue_status(sharename, &old_status);
- if (old_status.qcount != qcount)
- DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
- old_status.qcount, qcount, sharename));
-
- /* store the new queue status structure */
- slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
- key = string_tdb_data(keystr);
-
- status.qcount = qcount;
- data.dptr = (uint8 *)&status;
- data.dsize = sizeof(status);
- tdb_store(pdb->tdb, key, data, TDB_REPLACE);
-
- /*
- * Update the cache time again. We want to do this call
- * as little as possible...
- */
-
- slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
- tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
-
- /* clear the msg pending record for this queue */
-
- snprintf(keystr, sizeof(keystr), "MSG_PENDING/%s", sharename);
-
- if ( !tdb_store_uint32( pdb->tdb, keystr, 0 ) ) {
- /* log a message but continue on */
-
- DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
- sharename));
- }
-
- release_print_db( pdb );
-
- return;
-}
-
-/****************************************************************************
- Update the internal database from the system print queue for a queue.
- obtain a lock on the print queue before proceeding (needed when mutiple
- smbd processes maytry to update the lpq cache concurrently).
-****************************************************************************/
-
-static void print_queue_update_with_lock( const char *sharename,
- struct printif *current_printif,
- char *lpq_command, char *lprm_command )
-{
- fstring keystr;
- struct tdb_print_db *pdb;
-
- DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
- pdb = get_print_db_byname(sharename);
- if (!pdb)
- return;
-
- if ( !print_cache_expired(sharename, False) ) {
- DEBUG(5,("print_queue_update_with_lock: print cache for %s is still ok\n", sharename));
- release_print_db(pdb);
- return;
- }
-
- /*
- * Check to see if someone else is doing this update.
- * This is essentially a mutex on the update.
- */
-
- if (get_updating_pid(sharename) != -1) {
- release_print_db(pdb);
- return;
- }
-
- /* Lock the queue for the database update */
-
- slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
- /* Only wait 10 seconds for this. */
- if (tdb_lock_bystring_with_timeout(pdb->tdb, keystr, 10) == -1) {
- DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
- release_print_db(pdb);
- return;
- }
-
- /*
- * Ensure that no one else got in here.
- * If the updating pid is still -1 then we are
- * the winner.
- */
-
- if (get_updating_pid(sharename) != -1) {
- /*
- * Someone else is doing the update, exit.
- */
- tdb_unlock_bystring(pdb->tdb, keystr);
- release_print_db(pdb);
- return;
- }
-
- /*
- * We're going to do the update ourselves.
- */
-
- /* Tell others we're doing the update. */
- set_updating_pid(sharename, True);
-
- /*
- * Allow others to enter and notice we're doing
- * the update.
- */
-
- tdb_unlock_bystring(pdb->tdb, keystr);
-
- /* do the main work now */
-
- print_queue_update_internal( sharename, current_printif,
- lpq_command, lprm_command );
-
- /* Delete our pid from the db. */
- set_updating_pid(sharename, False);
- release_print_db(pdb);
-}
-
-/****************************************************************************
-this is the receive function of the background lpq updater
-****************************************************************************/
-static void print_queue_receive(struct messaging_context *msg,
- void *private_data,
- uint32_t msg_type,
- struct server_id server_id,
- DATA_BLOB *data)
-{
- fstring sharename;
- char *lpqcommand = NULL, *lprmcommand = NULL;
- int printing_type;
- size_t len;
-
- len = tdb_unpack( (uint8 *)data->data, data->length, "fdPP",
- sharename,
- &printing_type,
- &lpqcommand,
- &lprmcommand );
-
- if ( len == -1 ) {
- SAFE_FREE(lpqcommand);
- SAFE_FREE(lprmcommand);
- DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
- return;
- }
-
- print_queue_update_with_lock(sharename,
- get_printer_fns_from_type((enum printing_types)printing_type),
- lpqcommand, lprmcommand );
-
- SAFE_FREE(lpqcommand);
- SAFE_FREE(lprmcommand);
- return;
-}
-
-static void printing_pause_fd_handler(struct tevent_context *ev,
- struct tevent_fd *fde,
- uint16_t flags,
- void *private_data)
-{
- /*
- * If pause_pipe[1] is closed it means the parent smbd
- * and children exited or aborted.
- */
- exit_server_cleanly(NULL);
-}
-
-static void add_child_pid(pid_t pid)
-{
- extern struct child_pid *children;
- struct child_pid *child;
- extern int num_children;
-
- child = SMB_MALLOC_P(struct child_pid);
- if (child == NULL) {
- DEBUG(0, ("Could not add child struct -- malloc failed\n"));
- return;
- }
- child->pid = pid;
- DLIST_ADD(children, child);
- num_children += 1;
-}
-
-static pid_t background_lpq_updater_pid = -1;
-
-/****************************************************************************
-main thread of the background lpq updater
-****************************************************************************/
-void start_background_queue(void)
-{
- /* Use local variables for this as we don't
- * need to save the parent side of this, just
- * ensure it closes when the process exits.
- */
- int pause_pipe[2];
-
- DEBUG(3,("start_background_queue: Starting background LPQ thread\n"));
-
- if (pipe(pause_pipe) == -1) {
- DEBUG(5,("start_background_queue: cannot create pipe. %s\n", strerror(errno) ));
- exit(1);
- }
-
- background_lpq_updater_pid = sys_fork();
-
- if (background_lpq_updater_pid == -1) {
- DEBUG(5,("start_background_queue: background LPQ thread failed to start. %s\n", strerror(errno) ));
- exit(1);
- }
-
- /* Track the printing pid along with other smbd children */
- add_child_pid(background_lpq_updater_pid);
-
- if(background_lpq_updater_pid == 0) {
- struct tevent_fd *fde;
- int ret;
-
- /* Child. */
- DEBUG(5,("start_background_queue: background LPQ thread started\n"));
-
- close(pause_pipe[0]);
- pause_pipe[0] = -1;
-
- if (!NT_STATUS_IS_OK(reinit_after_fork(smbd_messaging_context(),
- smbd_event_context(),
- true))) {
- DEBUG(0,("reinit_after_fork() failed\n"));
- smb_panic("reinit_after_fork() failed");
- }
-
- smbd_setup_sig_term_handler();
- smbd_setup_sig_hup_handler();
-
- if (!serverid_register_self(FLAG_MSG_GENERAL|FLAG_MSG_SMBD
- |FLAG_MSG_PRINT_GENERAL)) {
- exit(1);
- }
-
- if (!locking_init()) {
- exit(1);
- }
-
- messaging_register(smbd_messaging_context(), NULL,
- MSG_PRINTER_UPDATE, print_queue_receive);
-
- fde = tevent_add_fd(smbd_event_context(), smbd_event_context(),
- pause_pipe[1], TEVENT_FD_READ,
- printing_pause_fd_handler,
- NULL);
- if (!fde) {
- DEBUG(0,("tevent_add_fd() failed for pause_pipe\n"));
- smb_panic("tevent_add_fd() failed for pause_pipe");
- }
-
- DEBUG(5,("start_background_queue: background LPQ thread waiting for messages\n"));
- ret = tevent_loop_wait(smbd_event_context());
- /* should not be reached */
- DEBUG(0,("background_queue: tevent_loop_wait() exited with %d - %s\n",
- ret, (ret == 0) ? "out of events" : strerror(errno)));
- exit(1);
- }
-
- close(pause_pipe[1]);
-}
-
-/****************************************************************************
-update the internal database from the system print queue for a queue
-****************************************************************************/
-
-static void print_queue_update(int snum, bool force)
-{
- fstring key;
- fstring sharename;
- char *lpqcommand = NULL;
- char *lprmcommand = NULL;
- uint8 *buffer = NULL;
- size_t len = 0;
- size_t newlen;
- struct tdb_print_db *pdb;
- int type;
- struct printif *current_printif;
- TALLOC_CTX *ctx = talloc_tos();
-
- fstrcpy( sharename, lp_const_servicename(snum));
-
- /* don't strip out characters like '$' from the printername */
-
- lpqcommand = talloc_string_sub2(ctx,
- lp_lpqcommand(snum),
- "%p",
- PRINTERNAME(snum),
- false, false, false);
- if (!lpqcommand) {
- return;
- }
- lpqcommand = talloc_sub_advanced(ctx,
- lp_servicename(snum),
- current_user_info.unix_name,
- "",
- current_user.ut.gid,
- get_current_username(),
- current_user_info.domain,
- lpqcommand);
- if (!lpqcommand) {
- return;
- }
-
- lprmcommand = talloc_string_sub2(ctx,
- lp_lprmcommand(snum),
- "%p",
- PRINTERNAME(snum),
- false, false, false);
- if (!lprmcommand) {
- return;
- }
- lprmcommand = talloc_sub_advanced(ctx,
- lp_servicename(snum),
- current_user_info.unix_name,
- "",
- current_user.ut.gid,
- get_current_username(),
- current_user_info.domain,
- lprmcommand);
- if (!lprmcommand) {
- return;
- }
-
- /*
- * Make sure that the background queue process exists.
- * Otherwise just do the update ourselves
- */
-
- if ( force || background_lpq_updater_pid == -1 ) {
- DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
- current_printif = get_printer_fns( snum );
- print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand );
-
- return;
- }
-
- type = lp_printing(snum);
-
- /* get the length */
-
- len = tdb_pack( NULL, 0, "fdPP",
- sharename,
- type,
- lpqcommand,
- lprmcommand );
-
- buffer = SMB_XMALLOC_ARRAY( uint8, len );
-
- /* now pack the buffer */
- newlen = tdb_pack( buffer, len, "fdPP",
- sharename,
- type,
- lpqcommand,
- lprmcommand );
-
- SMB_ASSERT( newlen == len );
-
- DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
- "type = %d, lpq command = [%s] lprm command = [%s]\n",
- sharename, type, lpqcommand, lprmcommand ));
-
- /* here we set a msg pending record for other smbd processes
- to throttle the number of duplicate print_queue_update msgs
- sent. */
-
- pdb = get_print_db_byname(sharename);
- if (!pdb) {
- SAFE_FREE(buffer);
- return;
- }
-
- snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
-
- if ( !tdb_store_uint32( pdb->tdb, key, time(NULL) ) ) {
- /* log a message but continue on */
-
- DEBUG(0,("print_queue_update: failed to store MSG_PENDING flag for [%s]!\n",
- sharename));
- }
-
- release_print_db( pdb );
-
- /* finally send the message */
-
- messaging_send_buf(smbd_messaging_context(),
- pid_to_procid(background_lpq_updater_pid),
- MSG_PRINTER_UPDATE, (uint8 *)buffer, len);
-
- SAFE_FREE( buffer );
-
- return;
-}
-
-/****************************************************************************
- Create/Update an entry in the print tdb that will allow us to send notify
- updates only to interested smbd's.
-****************************************************************************/
-
-bool print_notify_register_pid(int snum)
-{
- TDB_DATA data;
- struct tdb_print_db *pdb = NULL;
- TDB_CONTEXT *tdb = NULL;
- const char *printername;
- uint32 mypid = (uint32)sys_getpid();
- bool ret = False;
- size_t i;
-
- /* if (snum == -1), then the change notify request was
- on a print server handle and we need to register on
- all print queus */
-
- if (snum == -1)
- {
- int num_services = lp_numservices();
- int idx;
-
- for ( idx=0; idx<num_services; idx++ ) {
- if (lp_snum_ok(idx) && lp_print_ok(idx) )
- print_notify_register_pid(idx);
- }
-
- return True;
- }
- else /* register for a specific printer */
- {
- printername = lp_const_servicename(snum);
- pdb = get_print_db_byname(printername);
- if (!pdb)
- return False;
- tdb = pdb->tdb;
- }
-
- if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
- DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
- printername));
- if (pdb)
- release_print_db(pdb);
- return False;
- }
-
- data = get_printer_notify_pid_list( tdb, printername, True );
-
- /* Add ourselves and increase the refcount. */
-
- for (i = 0; i < data.dsize; i += 8) {
- if (IVAL(data.dptr,i) == mypid) {
- uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
- SIVAL(data.dptr, i+4, new_refcount);
- break;
- }
- }
-
- if (i == data.dsize) {
- /* We weren't in the list. Realloc. */
- data.dptr = (uint8 *)SMB_REALLOC(data.dptr, data.dsize + 8);
- if (!data.dptr) {
- DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
- printername));
- goto done;
- }
- data.dsize += 8;
- SIVAL(data.dptr,data.dsize - 8,mypid);
- SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
- }
-
- /* Store back the record. */
- if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
- DEBUG(0,("print_notify_register_pid: Failed to update pid \
-list for printer %s\n", printername));
- goto done;
- }
-
- ret = True;
-
- done:
-
- tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
- if (pdb)
- release_print_db(pdb);
- SAFE_FREE(data.dptr);
- return ret;
-}
-
-/****************************************************************************
- Update an entry in the print tdb that will allow us to send notify
- updates only to interested smbd's.
-****************************************************************************/
-
-bool print_notify_deregister_pid(int snum)
-{
- TDB_DATA data;
- struct tdb_print_db *pdb = NULL;
- TDB_CONTEXT *tdb = NULL;
- const char *printername;
- uint32 mypid = (uint32)sys_getpid();
- size_t i;
- bool ret = False;
-
- /* if ( snum == -1 ), we are deregister a print server handle
- which means to deregister on all print queues */
-
- if (snum == -1)
- {
- int num_services = lp_numservices();
- int idx;
-
- for ( idx=0; idx<num_services; idx++ ) {
- if ( lp_snum_ok(idx) && lp_print_ok(idx) )
- print_notify_deregister_pid(idx);
- }
-
- return True;
- }
- else /* deregister a specific printer */
- {
- printername = lp_const_servicename(snum);
- pdb = get_print_db_byname(printername);
- if (!pdb)
- return False;
- tdb = pdb->tdb;
- }
-
- if (tdb_lock_bystring_with_timeout(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
- DEBUG(0,("print_notify_register_pid: Failed to lock \
-printer %s database\n", printername));
- if (pdb)
- release_print_db(pdb);
- return False;
- }
-
- data = get_printer_notify_pid_list( tdb, printername, True );
-
- /* Reduce refcount. Remove ourselves if zero. */
-
- for (i = 0; i < data.dsize; ) {
- if (IVAL(data.dptr,i) == mypid) {
- uint32 refcount = IVAL(data.dptr, i+4);
-
- refcount--;
-
- if (refcount == 0) {
- if (data.dsize - i > 8)
- memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
- data.dsize -= 8;
- continue;
- }
- SIVAL(data.dptr, i+4, refcount);
- }
-
- i += 8;
- }
-
- if (data.dsize == 0)
- SAFE_FREE(data.dptr);
-
- /* Store back the record. */
- if (tdb_store_bystring(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
- DEBUG(0,("print_notify_register_pid: Failed to update pid \
-list for printer %s\n", printername));
- goto done;
- }
-
- ret = True;
-
- done:
-
- tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
- if (pdb)
- release_print_db(pdb);
- SAFE_FREE(data.dptr);
- return ret;
-}
-
-/****************************************************************************
- Check if a jobid is valid. It is valid if it exists in the database.
-****************************************************************************/
-
-bool print_job_exists(const char* sharename, uint32 jobid)
-{
- struct tdb_print_db *pdb = get_print_db_byname(sharename);
- bool ret;
- uint32_t tmp;
-
- if (!pdb)
- return False;
- ret = tdb_exists(pdb->tdb, print_key(jobid, &tmp));
- release_print_db(pdb);
- return ret;
-}
-
-/****************************************************************************
- Give the fd used for a jobid.
-****************************************************************************/
-
-int print_job_fd(const char* sharename, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(sharename, jobid);
- if (!pjob)
- return -1;
- /* don't allow another process to get this info - it is meaningless */
- if (pjob->pid != sys_getpid())
- return -1;
- return pjob->fd;
-}
-
-/****************************************************************************
- Give the filename used for a jobid.
- Only valid for the process doing the spooling and when the job
- has not been spooled.
-****************************************************************************/
-
-char *print_job_fname(const char* sharename, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(sharename, jobid);
- if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
- return NULL;
- return pjob->filename;
-}
-
-
-/****************************************************************************
- Give the filename used for a jobid.
- Only valid for the process doing the spooling and when the job
- has not been spooled.
-****************************************************************************/
-
-NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(sharename, jobid);
-
- if ( !pjob )
- return NULL;
-
- return pjob->nt_devmode;
-}
-
-/****************************************************************************
- Set the place in the queue for a job.
-****************************************************************************/
-
-bool print_job_set_place(const char *sharename, uint32 jobid, int place)
-{
- DEBUG(2,("print_job_set_place not implemented yet\n"));
- return False;
-}
-
-/****************************************************************************
- Set the name of a job. Only possible for owner.
-****************************************************************************/
-
-bool print_job_set_name(const char *sharename, uint32 jobid, char *name)
-{
- struct printjob *pjob;
-
- pjob = print_job_find(sharename, jobid);
- if (!pjob || pjob->pid != sys_getpid())
- return False;
-
- fstrcpy(pjob->jobname, name);
- return pjob_store(sharename, jobid, pjob);
-}
-
-/***************************************************************************
- Remove a jobid from the 'jobs changed' list.
-***************************************************************************/
-
-static bool remove_from_jobs_changed(const char* sharename, uint32 jobid)
-{
- struct tdb_print_db *pdb = get_print_db_byname(sharename);
- TDB_DATA data, key;
- size_t job_count, i;
- bool ret = False;
- bool gotlock = False;
-
- if (!pdb) {
- return False;
- }
-
- ZERO_STRUCT(data);
-
- key = string_tdb_data("INFO/jobs_changed");
-
- if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1)
- goto out;
-
- gotlock = True;
-
- data = tdb_fetch(pdb->tdb, key);
-
- if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0))
- goto out;
-
- job_count = data.dsize / 4;
- for (i = 0; i < job_count; i++) {
- uint32 ch_jobid;
-
- ch_jobid = IVAL(data.dptr, i*4);
- if (ch_jobid == jobid) {
- if (i < job_count -1 )
- memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 );
- data.dsize -= 4;
- if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1)
- goto out;
- break;
- }
- }
-
- ret = True;
- out:
-
- if (gotlock)
- tdb_chainunlock(pdb->tdb, key);
- SAFE_FREE(data.dptr);
- release_print_db(pdb);
- if (ret)
- DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
- else
- DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
- return ret;
-}
-
-/****************************************************************************
- Delete a print job - don't update queue.
-****************************************************************************/
-
-static bool print_job_delete1(int snum, uint32 jobid)
-{
- const char* sharename = lp_const_servicename(snum);
- struct printjob *pjob = print_job_find(sharename, jobid);
- int result = 0;
- struct printif *current_printif = get_printer_fns( snum );
-
- if (!pjob)
- return False;
-
- /*
- * If already deleting just return.
- */
-
- if (pjob->status == LPQ_DELETING)
- return True;
-
- /* Hrm - we need to be able to cope with deleting a job before it
- has reached the spooler. Just mark it as LPQ_DELETING and
- let the print_queue_update() code rmeove the record */
-
-
- if (pjob->sysjob == -1) {
- DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
- }
-
- /* Set the tdb entry to be deleting. */
-
- pjob->status = LPQ_DELETING;
- pjob_store(sharename, jobid, pjob);
-
- if (pjob->spooled && pjob->sysjob != -1)
- {
- result = (*(current_printif->job_delete))(
- PRINTERNAME(snum),
- lp_lprmcommand(snum),
- pjob);
-
- /* Delete the tdb entry if the delete succeeded or the job hasn't
- been spooled. */
-
- if (result == 0) {
- struct tdb_print_db *pdb = get_print_db_byname(sharename);
- int njobs = 1;
-
- if (!pdb)
- return False;
- pjob_delete(sharename, jobid);
- /* Ensure we keep a rough count of the number of total jobs... */
- tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, -1);
- release_print_db(pdb);
- }
- }
-
- remove_from_jobs_changed( sharename, jobid );
-
- return (result == 0);
-}
-
-/****************************************************************************
- Return true if the current user owns the print job.
-****************************************************************************/
-
-static bool is_owner(struct auth_serversupplied_info *server_info,
- const char *servicename,
- uint32 jobid)
-{
- struct printjob *pjob = print_job_find(servicename, jobid);
-
- if (!pjob || !server_info)
- return False;
-
- return strequal(pjob->user, server_info->sanitized_username);
-}
-
-/****************************************************************************
- Delete a print job.
-****************************************************************************/
-
-bool print_job_delete(struct auth_serversupplied_info *server_info, int snum,
- uint32 jobid, WERROR *errcode)
-{
- const char* sharename = lp_const_servicename( snum );
- struct printjob *pjob;
- bool owner;
- char *fname;
-
- *errcode = WERR_OK;
-
- owner = is_owner(server_info, lp_const_servicename(snum), jobid);
-
- /* Check access against security descriptor or whether the user
- owns their job. */
-
- if (!owner &&
- !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
- DEBUG(3, ("delete denied by security descriptor\n"));
- *errcode = WERR_ACCESS_DENIED;
-
- /* BEGIN_ADMIN_LOG */
- sys_adminlog( LOG_ERR,
- "Permission denied-- user not allowed to delete, \
-pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(server_info->utok.uid),
- PRINTERNAME(snum) );
- /* END_ADMIN_LOG */
-
- return False;
- }
-
- /*
- * get the spooled filename of the print job
- * if this works, then the file has not been spooled
- * to the underlying print system. Just delete the
- * spool file & return.
- */
-
- if ( (fname = print_job_fname( sharename, jobid )) != NULL )
- {
- /* remove the spool file */
- DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
- if ( unlink( fname ) == -1 ) {
- *errcode = map_werror_from_unix(errno);
- return False;
- }
- }
-
- if (!print_job_delete1(snum, jobid)) {
- *errcode = WERR_ACCESS_DENIED;
- return False;
- }
-
- /* force update the database and say the delete failed if the
- job still exists */
-
- print_queue_update(snum, True);
-
- pjob = print_job_find(sharename, jobid);
- if ( pjob && (pjob->status != LPQ_DELETING) )
- *errcode = WERR_ACCESS_DENIED;
-
- return (pjob == NULL );
-}
-
-/****************************************************************************
- Pause a job.
-****************************************************************************/
-
-bool print_job_pause(struct auth_serversupplied_info *server_info, int snum,
- uint32 jobid, WERROR *errcode)
-{
- const char* sharename = lp_const_servicename(snum);
- struct printjob *pjob;
- int ret = -1;
- struct printif *current_printif = get_printer_fns( snum );
-
- pjob = print_job_find(sharename, jobid);
-
- if (!pjob || !server_info) {
- DEBUG(10, ("print_job_pause: no pjob or user for jobid %u\n",
- (unsigned int)jobid ));
- return False;
- }
-
- if (!pjob->spooled || pjob->sysjob == -1) {
- DEBUG(10, ("print_job_pause: not spooled or bad sysjob = %d for jobid %u\n",
- (int)pjob->sysjob, (unsigned int)jobid ));
- return False;
- }
-
- if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
- !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
- DEBUG(3, ("pause denied by security descriptor\n"));
-
- /* BEGIN_ADMIN_LOG */
- sys_adminlog( LOG_ERR,
- "Permission denied-- user not allowed to delete, \
-pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(server_info->utok.uid),
- PRINTERNAME(snum) );
- /* END_ADMIN_LOG */
-
- *errcode = WERR_ACCESS_DENIED;
- return False;
- }
-
- /* need to pause the spooled entry */
- ret = (*(current_printif->job_pause))(snum, pjob);
-
- if (ret != 0) {
- *errcode = WERR_INVALID_PARAM;
- return False;
- }
-
- /* force update the database */
- print_cache_flush(lp_const_servicename(snum));
-
- /* Send a printer notify message */
-
- notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);
-
- /* how do we tell if this succeeded? */
-
- return True;
-}
-
-/****************************************************************************
- Resume a job.
-****************************************************************************/
-
-bool print_job_resume(struct auth_serversupplied_info *server_info, int snum,
- uint32 jobid, WERROR *errcode)
-{
- const char *sharename = lp_const_servicename(snum);
- struct printjob *pjob;
- int ret;
- struct printif *current_printif = get_printer_fns( snum );
-
- pjob = print_job_find(sharename, jobid);
-
- if (!pjob || !server_info) {
- DEBUG(10, ("print_job_resume: no pjob or user for jobid %u\n",
- (unsigned int)jobid ));
- return False;
- }
-
- if (!pjob->spooled || pjob->sysjob == -1) {
- DEBUG(10, ("print_job_resume: not spooled or bad sysjob = %d for jobid %u\n",
- (int)pjob->sysjob, (unsigned int)jobid ));
- return False;
- }
-
- if (!is_owner(server_info, lp_const_servicename(snum), jobid) &&
- !print_access_check(server_info, snum, JOB_ACCESS_ADMINISTER)) {
- DEBUG(3, ("resume denied by security descriptor\n"));
- *errcode = WERR_ACCESS_DENIED;
-
- /* BEGIN_ADMIN_LOG */
- sys_adminlog( LOG_ERR,
- "Permission denied-- user not allowed to delete, \
-pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(server_info->utok.uid),
- PRINTERNAME(snum) );
- /* END_ADMIN_LOG */
- return False;
- }
-
- ret = (*(current_printif->job_resume))(snum, pjob);
-
- if (ret != 0) {
- *errcode = WERR_INVALID_PARAM;
- return False;
- }
-
- /* force update the database */
- print_cache_flush(lp_const_servicename(snum));
-
- /* Send a printer notify message */
-
- notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);
-
- return True;
-}
-
-/****************************************************************************
- Write to a print file.
-****************************************************************************/
-
-ssize_t print_job_write(int snum, uint32 jobid, const char *buf, SMB_OFF_T pos, size_t size)
-{
- const char* sharename = lp_const_servicename(snum);
- ssize_t return_code;
- struct printjob *pjob;
-
- pjob = print_job_find(sharename, jobid);
-
- if (!pjob)
- return -1;
- /* don't allow another process to get this info - it is meaningless */
- if (pjob->pid != sys_getpid())
- return -1;
-
- return_code = write_data_at_offset(pjob->fd, buf, size, pos);
-
- if (return_code>0) {
- pjob->size += size;
- pjob_store(sharename, jobid, pjob);
- }
- return return_code;
-}
-
-/****************************************************************************
- Get the queue status - do not update if db is out of date.
-****************************************************************************/
-
-static int get_queue_status(const char* sharename, print_status_struct *status)
-{
- fstring keystr;
- TDB_DATA data;
- struct tdb_print_db *pdb = get_print_db_byname(sharename);
- int len;
-
- if (status) {
- ZERO_STRUCTP(status);
- }
-
- if (!pdb)
- return 0;
-
- if (status) {
- fstr_sprintf(keystr, "STATUS/%s", sharename);
- data = tdb_fetch(pdb->tdb, string_tdb_data(keystr));
- if (data.dptr) {
- if (data.dsize == sizeof(print_status_struct))
- /* this memcpy is ok since the status struct was
- not packed before storing it in the tdb */
- memcpy(status, data.dptr, sizeof(print_status_struct));
- SAFE_FREE(data.dptr);
- }
- }
- len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
- release_print_db(pdb);
- return (len == -1 ? 0 : len);
-}
-
-/****************************************************************************
- Determine the number of jobs in a queue.
-****************************************************************************/
-
-int print_queue_length(int snum, print_status_struct *pstatus)
-{
- const char* sharename = lp_const_servicename( snum );
- print_status_struct status;
- int len;
-
- ZERO_STRUCT( status );
-
- /* make sure the database is up to date */
- if (print_cache_expired(lp_const_servicename(snum), True))
- print_queue_update(snum, False);
-
- /* also fetch the queue status */
- memset(&status, 0, sizeof(status));
- len = get_queue_status(sharename, &status);
-
- if (pstatus)
- *pstatus = status;
-
- return len;
-}
-
-/***************************************************************************
- Allocate a jobid. Hold the lock for as short a time as possible.
-***************************************************************************/
-
-static bool allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid)
-{
- int i;
- uint32 jobid;
-
- *pjobid = (uint32)-1;
-
- for (i = 0; i < 3; i++) {
- /* Lock the database - only wait 20 seconds. */
- if (tdb_lock_bystring_with_timeout(pdb->tdb, "INFO/nextjob", 20) == -1) {
- DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename));
- return False;
- }
-
- if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
- if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
- DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
- sharename));
- tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
- return False;
- }
- DEBUG(10,("allocate_print_jobid: no existing jobid in %s\n", sharename));
- jobid = 0;
- }
-
- DEBUG(10,("allocate_print_jobid: read jobid %u from %s\n", jobid, sharename));
-
- jobid = NEXT_JOBID(jobid);
-
- if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
- DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
- tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
- return False;
- }
-
- /* We've finished with the INFO/nextjob lock. */
- tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
-
- if (!print_job_exists(sharename, jobid)) {
- break;
- }
- DEBUG(10,("allocate_print_jobid: found jobid %u in %s\n", jobid, sharename));
- }
-
- if (i > 2) {
- DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
- sharename));
- /* Probably full... */
- errno = ENOSPC;
- return False;
- }
-
- /* Store a dummy placeholder. */
- {
- uint32_t tmp;
- TDB_DATA dum;
- dum.dptr = NULL;
- dum.dsize = 0;
- if (tdb_store(pdb->tdb, print_key(jobid, &tmp), dum,
- TDB_INSERT) == -1) {
- DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
- jobid ));
- return False;
- }
- }
-
- *pjobid = jobid;
- return True;
-}
-
-/***************************************************************************
- Append a jobid to the 'jobs changed' list.
-***************************************************************************/
-
-static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
-{
- TDB_DATA data;
- uint32 store_jobid;
-
- SIVAL(&store_jobid, 0, jobid);
- data.dptr = (uint8 *)&store_jobid;
- data.dsize = 4;
-
- DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
-
- return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"),
- data) == 0);
-}
-
-/***************************************************************************
- Start spooling a job - return the jobid.
-***************************************************************************/
-
-uint32 print_job_start(struct auth_serversupplied_info *server_info, int snum,
- const char *jobname, NT_DEVICEMODE *nt_devmode )
-{
- uint32 jobid;
- char *path;
- struct printjob pjob;
- const char *sharename = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(sharename);
- int njobs;
-
- errno = 0;
-
- if (!pdb)
- return (uint32)-1;
-
- if (!print_access_check(server_info, snum, PRINTER_ACCESS_USE)) {
- DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
- release_print_db(pdb);
- return (uint32)-1;
- }
-
- if (!print_time_access_check(lp_servicename(snum))) {
- DEBUG(3, ("print_job_start: job start denied by time check\n"));
- release_print_db(pdb);
- return (uint32)-1;
- }
-
- path = lp_pathname(snum);
-
- /* see if we have sufficient disk space */
- if (lp_minprintspace(snum)) {
- uint64_t dspace, dsize;
- if (sys_fsusage(path, &dspace, &dsize) == 0 &&
- dspace < 2*(uint64_t)lp_minprintspace(snum)) {
- DEBUG(3, ("print_job_start: disk space check failed.\n"));
- release_print_db(pdb);
- errno = ENOSPC;
- return (uint32)-1;
- }
- }
-
- /* for autoloaded printers, check that the printcap entry still exists */
- if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum))) {
- DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
- release_print_db(pdb);
- errno = ENOENT;
- return (uint32)-1;
- }
-
- /* Insure the maximum queue size is not violated */
- if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
- DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
- sharename, njobs, lp_maxprintjobs(snum) ));
- release_print_db(pdb);
- errno = ENOSPC;
- return (uint32)-1;
- }
-
- DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
- sharename, njobs, lp_maxprintjobs(snum) ));
-
- if (!allocate_print_jobid(pdb, snum, sharename, &jobid))
- goto fail;
-
- /* create the database entry */
-
- ZERO_STRUCT(pjob);
-
- pjob.pid = sys_getpid();
- pjob.sysjob = -1;
- pjob.fd = -1;
- pjob.starttime = time(NULL);
- pjob.status = LPQ_SPOOLING;
- pjob.size = 0;
- pjob.spooled = False;
- pjob.smbjob = True;
- pjob.nt_devmode = nt_devmode;
-
- fstrcpy(pjob.jobname, jobname);
-
- fstrcpy(pjob.user, lp_printjob_username(snum));
- standard_sub_advanced(sharename, server_info->sanitized_username,
- path, server_info->utok.gid,
- server_info->sanitized_username,
- pdb_get_domain(server_info->sam_account),
- pjob.user, sizeof(pjob.user)-1);
- /* ensure NULL termination */
- pjob.user[sizeof(pjob.user)-1] = '\0';
-
- fstrcpy(pjob.queuename, lp_const_servicename(snum));
-
- /* we have a job entry - now create the spool file */
- slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
- path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
- pjob.fd = mkstemp(pjob.filename);
-
- if (pjob.fd == -1) {
- if (errno == EACCES) {
- /* Common setup error, force a report. */
- DEBUG(0, ("print_job_start: insufficient permissions \
-to open spool file %s.\n", pjob.filename));
- } else {
- /* Normal case, report at level 3 and above. */
- DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
- DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
- }
- goto fail;
- }
-
- pjob_store(sharename, jobid, &pjob);
-
- /* Update the 'jobs changed' entry used by print_queue_status. */
- add_to_jobs_changed(pdb, jobid);
-
- /* Ensure we keep a rough count of the number of total jobs... */
- tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
-
- release_print_db(pdb);
-
- return jobid;
-
- fail:
- if (jobid != -1)
- pjob_delete(sharename, jobid);
-
- release_print_db(pdb);
-
- DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
- return (uint32)-1;
-}
-
-/****************************************************************************
- Update the number of pages spooled to jobid
-****************************************************************************/
-
-void print_job_endpage(int snum, uint32 jobid)
-{
- const char* sharename = lp_const_servicename(snum);
- struct printjob *pjob;
-
- pjob = print_job_find(sharename, jobid);
- if (!pjob)
- return;
- /* don't allow another process to get this info - it is meaningless */
- if (pjob->pid != sys_getpid())
- return;
-
- pjob->page_count++;
- pjob_store(sharename, jobid, pjob);
-}
-
-/****************************************************************************
- Print a file - called on closing the file. This spools the job.
- If normal close is false then we're tearing down the jobs - treat as an
- error.
-****************************************************************************/
-
-bool print_job_end(int snum, uint32 jobid, enum file_close_type close_type)
-{
- const char* sharename = lp_const_servicename(snum);
- struct printjob *pjob;
- int ret;
- SMB_STRUCT_STAT sbuf;
- struct printif *current_printif = get_printer_fns( snum );
-
- pjob = print_job_find(sharename, jobid);
-
- if (!pjob)
- return False;
-
- if (pjob->spooled || pjob->pid != sys_getpid())
- return False;
-
- if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
- (sys_fstat(pjob->fd, &sbuf, false) == 0)) {
- pjob->size = sbuf.st_ex_size;
- close(pjob->fd);
- pjob->fd = -1;
- } else {
-
- /*
- * Not a normal close or we couldn't stat the job file,
- * so something has gone wrong. Cleanup.
- */
- close(pjob->fd);
- pjob->fd = -1;
- DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
- goto fail;
- }
-
- /* Technically, this is not quite right. If the printer has a separator
- * page turned on, the NT spooler prints the separator page even if the
- * print job is 0 bytes. 010215 JRR */
- if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
- /* don't bother spooling empty files or something being deleted. */
- DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
- pjob->filename, pjob->size ? "deleted" : "zero length" ));
- unlink(pjob->filename);
- pjob_delete(sharename, jobid);
- return True;
- }
-
- ret = (*(current_printif->job_submit))(snum, pjob);
-
- if (ret)
- goto fail;
-
- /* The print job has been successfully handed over to the back-end */
-
- pjob->spooled = True;
- pjob->status = LPQ_QUEUED;
- pjob_store(sharename, jobid, pjob);
-
- /* make sure the database is up to date */
- if (print_cache_expired(lp_const_servicename(snum), True))
- print_queue_update(snum, False);
-
- return True;
-
-fail:
-
- /* The print job was not successfully started. Cleanup */
- /* Still need to add proper error return propagation! 010122:JRR */
- unlink(pjob->filename);
- pjob_delete(sharename, jobid);
- return False;
-}
-
-/****************************************************************************
- Get a snapshot of jobs in the system without traversing.
-****************************************************************************/
-
-static bool get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue)
-{
- TDB_DATA data, cgdata;
- print_queue_struct *queue = NULL;
- uint32 qcount = 0;
- uint32 extra_count = 0;
- int total_count = 0;
- size_t len = 0;
- uint32 i;
- int max_reported_jobs = lp_max_reported_jobs(snum);
- bool ret = False;
- const char* sharename = lp_servicename(snum);
-
- /* make sure the database is up to date */
- if (print_cache_expired(lp_const_servicename(snum), True))
- print_queue_update(snum, False);
-
- *pcount = 0;
- *ppqueue = NULL;
-
- ZERO_STRUCT(data);
- ZERO_STRUCT(cgdata);
-
- /* Get the stored queue data. */
- data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/linear_queue_array"));
-
- if (data.dptr && data.dsize >= sizeof(qcount))
- len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount);
-
- /* Get the changed jobs list. */
- cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed"));
- if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
- extra_count = cgdata.dsize/4;
-
- DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
-
- /* Allocate the queue size. */
- if (qcount == 0 && extra_count == 0)
- goto out;
-
- if ((queue = SMB_MALLOC_ARRAY(print_queue_struct, qcount + extra_count)) == NULL)
- goto out;
-
- /* Retrieve the linearised queue data. */
-
- for( i = 0; i < qcount; i++) {
- uint32 qjob, qsize, qpage_count, qstatus, qpriority, qtime;
- len += tdb_unpack(data.dptr + len, data.dsize - len, "ddddddff",
- &qjob,
- &qsize,
- &qpage_count,
- &qstatus,
- &qpriority,
- &qtime,
- queue[i].fs_user,
- queue[i].fs_file);
- queue[i].job = qjob;
- queue[i].size = qsize;
- queue[i].page_count = qpage_count;
- queue[i].status = qstatus;
- queue[i].priority = qpriority;
- queue[i].time = qtime;
- }
-
- total_count = qcount;
-
- /* Add in the changed jobids. */
- for( i = 0; i < extra_count; i++) {
- uint32 jobid;
- struct printjob *pjob;
-
- jobid = IVAL(cgdata.dptr, i*4);
- DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
- pjob = print_job_find(lp_const_servicename(snum), jobid);
- if (!pjob) {
- DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
- remove_from_jobs_changed(sharename, jobid);
- continue;
- }
-
- queue[total_count].job = jobid;
- queue[total_count].size = pjob->size;
- queue[total_count].page_count = pjob->page_count;
- queue[total_count].status = pjob->status;
- queue[total_count].priority = 1;
- queue[total_count].time = pjob->starttime;
- fstrcpy(queue[total_count].fs_user, pjob->user);
- fstrcpy(queue[total_count].fs_file, pjob->jobname);
- total_count++;
- }
-
- /* Sort the queue by submission time otherwise they are displayed
- in hash order. */
-
- TYPESAFE_QSORT(queue, total_count, printjob_comp);
-
- DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
-
- if (max_reported_jobs && total_count > max_reported_jobs)
- total_count = max_reported_jobs;
-
- *ppqueue = queue;
- *pcount = total_count;
-
- ret = True;
-
- out:
-
- SAFE_FREE(data.dptr);
- SAFE_FREE(cgdata.dptr);
- return ret;
-}
-
-/****************************************************************************
- Get a printer queue listing.
- set queue = NULL and status = NULL if you just want to update the cache
-****************************************************************************/
-
-int print_queue_status(int snum,
- print_queue_struct **ppqueue,
- print_status_struct *status)
-{
- fstring keystr;
- TDB_DATA data, key;
- const char *sharename;
- struct tdb_print_db *pdb;
- int count = 0;
-
- /* make sure the database is up to date */
-
- if (print_cache_expired(lp_const_servicename(snum), True))
- print_queue_update(snum, False);
-
- /* return if we are done */
- if ( !ppqueue || !status )
- return 0;
-
- *ppqueue = NULL;
- sharename = lp_const_servicename(snum);
- pdb = get_print_db_byname(sharename);
-
- if (!pdb)
- return 0;
-
- /*
- * Fetch the queue status. We must do this first, as there may
- * be no jobs in the queue.
- */
-
- ZERO_STRUCTP(status);
- slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
- key = string_tdb_data(keystr);
-
- data = tdb_fetch(pdb->tdb, key);
- if (data.dptr) {
- if (data.dsize == sizeof(*status)) {
- /* this memcpy is ok since the status struct was
- not packed before storing it in the tdb */
- memcpy(status, data.dptr, sizeof(*status));
- }
- SAFE_FREE(data.dptr);
- }
-
- /*
- * Now, fetch the print queue information. We first count the number
- * of entries, and then only retrieve the queue if necessary.
- */
-
- if (!get_stored_queue_info(pdb, snum, &count, ppqueue)) {
- release_print_db(pdb);
- return 0;
- }
-
- release_print_db(pdb);
- return count;
-}
-
-/****************************************************************************
- Pause a queue.
-****************************************************************************/
-
-WERROR print_queue_pause(struct auth_serversupplied_info *server_info, int snum)
-{
- int ret;
- struct printif *current_printif = get_printer_fns( snum );
-
- if (!print_access_check(server_info, snum,
- PRINTER_ACCESS_ADMINISTER)) {
- return WERR_ACCESS_DENIED;
- }
-
-
- become_root();
-
- ret = (*(current_printif->queue_pause))(snum);
-
- unbecome_root();
-
- if (ret != 0) {
- return WERR_INVALID_PARAM;
- }
-
- /* force update the database */
- print_cache_flush(lp_const_servicename(snum));
-
- /* Send a printer notify message */
-
- notify_printer_status(snum, PRINTER_STATUS_PAUSED);
-
- return WERR_OK;
-}
-
-/****************************************************************************
- Resume a queue.
-****************************************************************************/
-
-WERROR print_queue_resume(struct auth_serversupplied_info *server_info, int snum)
-{
- int ret;
- struct printif *current_printif = get_printer_fns( snum );
-
- if (!print_access_check(server_info, snum,
- PRINTER_ACCESS_ADMINISTER)) {
- return WERR_ACCESS_DENIED;
- }
-
- become_root();
-
- ret = (*(current_printif->queue_resume))(snum);
-
- unbecome_root();
-
- if (ret != 0) {
- return WERR_INVALID_PARAM;
- }
-
- /* make sure the database is up to date */
- if (print_cache_expired(lp_const_servicename(snum), True))
- print_queue_update(snum, True);
-
- /* Send a printer notify message */
-
- notify_printer_status(snum, PRINTER_STATUS_OK);
-
- return WERR_OK;
-}
-
-/****************************************************************************
- Purge a queue - implemented by deleting all jobs that we can delete.
-****************************************************************************/
-
-WERROR print_queue_purge(struct auth_serversupplied_info *server_info, int snum)
-{
- print_queue_struct *queue;
- print_status_struct status;
- int njobs, i;
- bool can_job_admin;
-
- /* Force and update so the count is accurate (i.e. not a cached count) */
- print_queue_update(snum, True);
-
- can_job_admin = print_access_check(server_info, snum,
- JOB_ACCESS_ADMINISTER);
- njobs = print_queue_status(snum, &queue, &status);
-
- if ( can_job_admin )
- become_root();
-
- for (i=0;i<njobs;i++) {
- bool owner = is_owner(server_info, lp_const_servicename(snum),
- queue[i].job);
-
- if (owner || can_job_admin) {
- print_job_delete1(snum, queue[i].job);
- }
- }
-
- if ( can_job_admin )
- unbecome_root();
-
- /* update the cache */
- print_queue_update( snum, True );
-
- SAFE_FREE(queue);
-
- return WERR_OK;
-}
+++ /dev/null
-/*
- Unix SMB/Netbios implementation.
- Version 3.0
- printing backend routines
- Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) Jeremy Allison 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 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-#include "printing.h"
-
-static struct tdb_print_db *print_db_head;
-
-/****************************************************************************
- Function to find or create the printer specific job tdb given a printername.
- Limits the number of tdb's open to MAX_PRINT_DBS_OPEN.
-****************************************************************************/
-
-struct tdb_print_db *get_print_db_byname(const char *printername)
-{
- struct tdb_print_db *p = NULL, *last_entry = NULL;
- int num_open = 0;
- char *printdb_path = NULL;
- bool done_become_root = False;
-
- SMB_ASSERT(printername != NULL);
-
- for (p = print_db_head, last_entry = print_db_head; p; p = p->next) {
- /* Ensure the list terminates... JRA. */
- SMB_ASSERT(p->next != print_db_head);
-
- if (p->tdb && strequal(p->printer_name, printername)) {
- DLIST_PROMOTE(print_db_head, p);
- p->ref_count++;
- return p;
- }
- num_open++;
- last_entry = p;
- }
-
- /* Not found. */
- if (num_open >= MAX_PRINT_DBS_OPEN) {
- /* Try and recycle the last entry. */
- if (print_db_head && last_entry) {
- DLIST_PROMOTE(print_db_head, last_entry);
- }
-
- for (p = print_db_head; p; p = p->next) {
- if (p->ref_count)
- continue;
- if (p->tdb) {
- if (tdb_close(print_db_head->tdb)) {
- DEBUG(0,("get_print_db: Failed to close tdb for printer %s\n",
- print_db_head->printer_name ));
- return NULL;
- }
- }
- p->tdb = NULL;
- p->ref_count = 0;
- memset(p->printer_name, '\0', sizeof(p->printer_name));
- break;
- }
- if (p && print_db_head) {
- DLIST_PROMOTE(print_db_head, p);
- p = print_db_head;
- }
- }
-
- if (!p) {
- /* Create one. */
- p = SMB_MALLOC_P(struct tdb_print_db);
- if (!p) {
- DEBUG(0,("get_print_db: malloc fail !\n"));
- return NULL;
- }
- ZERO_STRUCTP(p);
- DLIST_ADD(print_db_head, p);
- }
-
- if (asprintf(&printdb_path, "%s%s.tdb",
- cache_path("printing/"),
- printername) < 0) {
- DLIST_REMOVE(print_db_head, p);
- SAFE_FREE(p);
- return NULL;
- }
-
- if (geteuid() != sec_initial_uid()) {
- become_root();
- done_become_root = True;
- }
-
- p->tdb = tdb_open_log(printdb_path, 5000, TDB_DEFAULT, O_RDWR|O_CREAT,
- 0600);
-
- if (done_become_root)
- unbecome_root();
-
- if (!p->tdb) {
- DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n",
- printdb_path ));
- DLIST_REMOVE(print_db_head, p);
- SAFE_FREE(printdb_path);
- SAFE_FREE(p);
- return NULL;
- }
- SAFE_FREE(printdb_path);
- fstrcpy(p->printer_name, printername);
- p->ref_count++;
- return p;
-}
-
-/***************************************************************************
- Remove a reference count.
-****************************************************************************/
-
-void release_print_db( struct tdb_print_db *pdb)
-{
- pdb->ref_count--;
- SMB_ASSERT(pdb->ref_count >= 0);
-}
-
-/***************************************************************************
- Close all open print db entries.
-****************************************************************************/
-
-void close_all_print_db(void)
-{
- struct tdb_print_db *p = NULL, *next_p = NULL;
-
- for (p = print_db_head; p; p = next_p) {
- next_p = p->next;
-
- if (p->tdb)
- tdb_close(p->tdb);
- DLIST_REMOVE(print_db_head, p);
- ZERO_STRUCTP(p);
- SAFE_FREE(p);
- }
-}
-
-
-/****************************************************************************
- Fetch and clean the pid_t record list for all pids interested in notify
- messages. data needs freeing on exit.
-****************************************************************************/
-
-TDB_DATA get_printer_notify_pid_list(TDB_CONTEXT *tdb, const char *printer_name, bool cleanlist)
-{
- TDB_DATA data;
- size_t i;
-
- ZERO_STRUCT(data);
-
- data = tdb_fetch_bystring( tdb, NOTIFY_PID_LIST_KEY );
-
- if (!data.dptr) {
- ZERO_STRUCT(data);
- return data;
- }
-
- if (data.dsize % 8) {
- DEBUG(0,("get_printer_notify_pid_list: Size of record for printer %s not a multiple of 8 !\n", printer_name ));
- tdb_delete_bystring(tdb, NOTIFY_PID_LIST_KEY );
- SAFE_FREE(data.dptr);
- ZERO_STRUCT(data);
- return data;
- }
-
- if (!cleanlist)
- return data;
-
- /*
- * Weed out all dead entries.
- */
-
- for( i = 0; i < data.dsize; i += 8) {
- pid_t pid = (pid_t)IVAL(data.dptr, i);
-
- if (pid == sys_getpid())
- continue;
-
- /* Entry is dead if process doesn't exist or refcount is zero. */
-
- while ((i < data.dsize) && ((IVAL(data.dptr, i + 4) == 0) || !process_exists_by_pid(pid))) {
-
- /* Refcount == zero is a logic error and should never happen. */
- if (IVAL(data.dptr, i + 4) == 0) {
- DEBUG(0,("get_printer_notify_pid_list: Refcount == 0 for pid = %u printer %s !\n",
- (unsigned int)pid, printer_name ));
- }
-
- if (data.dsize - i > 8)
- memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
- data.dsize -= 8;
- }
- }
-
- return data;
-}
-
-
+++ /dev/null
-Virtual line printer test program (vlp)
-=======================================
-
-This can be useful for testing/debugging Samba print code. It gives you a
-virtual full-function printer.
-
-Setup
-
-Set up Samba to use vlp.
- In your smb.conf file under [global], add the following option:
- printing = vlp
- and then add any number of print shares, without needing to make them
- really exist.
-
- [testprinter]
- printable = yes
-
- is all you need for the most basic virtual printer.
-
+++ /dev/null
-/*
- Unix SMB/Netbios implementation.
-
- Virtual lp system for printer testing
-
- Copyright (C) Tim Potter 2000
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "includes.h"
-
-#ifdef malloc
-#undef malloc
-#endif
-
-#define PRINT_FIRSTJOB "100"
-
-static TDB_CONTEXT *tdb;
-
-struct vlp_job {
- fstring owner;
- int jobid;
- fstring jobname;
- int size;
- int status;
- time_t submit_time;
- int deleted;
-};
-
-/* Print usage */
-
-static void usage(void)
-{
- printf("Usage: vlp tdbfile=/tmp/vlp.tdb lpq|lprm|print|queuepause|queueresume|"
- "lppause|lpresume [args]\n");
-}
-
-/* Return an array of vlp jobs that is the printer queue */
-
-static void get_job_list(char *printer, struct vlp_job **job_list,
- int *num_jobs)
-{
- fstring keystr;
- TDB_DATA data;
-
- slprintf(keystr, sizeof(keystr) - 1, "LPQ/%s", printer);
- data = tdb_fetch_bystring(tdb, keystr);
-
- *job_list = (struct vlp_job *)data.dptr;
- *num_jobs = data.dsize / sizeof(struct vlp_job);
-}
-
-/* Store an array of vl jobs for the queue */
-
-static void set_job_list(char *printer, struct vlp_job *job_list,
- int num_jobs)
-{
- fstring keystr;
- TDB_DATA data;
-
- slprintf(keystr, sizeof(keystr) - 1, "LPQ/%s", printer);
-
- data.dptr = (unsigned char *)job_list;
- data.dsize = num_jobs * sizeof(struct vlp_job);
- tdb_store_bystring(tdb, keystr, data, TDB_REPLACE);
-}
-
-/* Return the next job number for a printer */
-
-static int next_jobnum(char *printer)
-{
- fstring keystr;
- int jobnum;
-
- slprintf(keystr, sizeof(keystr) - 1, "JOBNUM/%s", printer);
-
- tdb_lock_bystring(tdb, keystr);
-
- jobnum = tdb_fetch_int32(tdb, keystr);
-
- /* Create next job index if none exists */
-
- if (jobnum == -1) {
- jobnum = atoi(PRINT_FIRSTJOB);
- }
-
- jobnum++;
- tdb_store_int32(tdb, keystr, jobnum);
-
- tdb_unlock_bystring(tdb, keystr);
-
- return jobnum;
-}
-
-static void set_printer_status(char *printer, int status)
-{
- fstring keystr;
- int result;
-
- slprintf(keystr, sizeof(keystr) - 1, "STATUS/%s", printer);
- result = tdb_store_int32(tdb, keystr, status);
-}
-
-static int get_printer_status(char *printer)
-{
- fstring keystr;
- TDB_DATA data;
-
- slprintf(keystr, sizeof(keystr) - 1, "STATUS/%s", printer);
-
- data.dptr = (unsigned char *)keystr;
- data.dsize = strlen(keystr) + 1;
-
- if (!tdb_exists(tdb, data)) {
- set_printer_status(printer, LPSTAT_OK);
- return LPSTAT_OK;
- }
-
- return tdb_fetch_int32(tdb, keystr);
-}
-
-/* Display printer queue */
-
-static int lpq_command(int argc, char **argv)
-{
- char *printer;
- struct vlp_job *job_list = NULL;
- int i, num_jobs, job_count = 0;
-
- if (argc != 2) {
- printf("Usage: lpq <printername>\n");
- return 1;
- }
-
- printer = argv[1];
-
- /* Display printer status */
-
- switch (get_printer_status(printer)) {
- case LPSTAT_OK:
- printf("enabled\n");
- break;
- case LPSTAT_STOPPED:
- printf("disabled\n");
- break;
- case LPSTAT_ERROR:
- default:
- printf("error\n");
- break;
- }
-
- /* Print queued documents */
-
- get_job_list(printer, &job_list, &num_jobs);
-
- for (i = 0; i < num_jobs; i++) {
- if (job_list[i].deleted) continue;
- printf("%d\t%d\t%d\t%ld\t%s\t%s\n", job_list[i].jobid,
- job_list[i].size,
- (i == 0 && job_list[i].status == LPQ_QUEUED) ?
- LPQ_SPOOLING : job_list[i].status,
- (long int)job_list[i].submit_time, job_list[i].owner,
- job_list[i].jobname);
- job_count++;
- }
-
- free(job_list);
-
- return 0;
-}
-
-/* Remove a job */
-
-static int lprm_command(int argc, char **argv)
-{
- char *printer;
- int jobid, num_jobs, i;
- struct vlp_job *job_list;
-
- if (argc < 3) {
- printf("Usage: lprm <printername> <jobid>\n");
- return 1;
- }
-
- printer = argv[1];
- jobid = atoi(argv[2]);
-
- get_job_list(printer, &job_list, &num_jobs);
-
- for (i = 0; i < num_jobs; i++) {
- if (job_list[i].jobid == jobid) {
- job_list[i].deleted = 1;
- set_job_list(printer, job_list, num_jobs);
- break;
- }
- }
-
- return 0;
-}
-
-/* print command = print-test %p %s */
-
-static int print_command(int argc, char **argv)
-{
- char *printer;
- fstring keystr;
- struct passwd *pw;
- TDB_DATA value, queue;
- struct vlp_job job;
-
- if (argc < 3) {
- printf("Usage: print <printername> <jobname>\n");
- return 1;
- }
-
- printer = argv[1];
-
- ZERO_STRUCT(job);
-
- /* Create a job record */
-
- slprintf(job.jobname, sizeof(job.jobname) - 1, "%s", argv[2]);
-
- if (!(pw = getpwuid(getuid()))) {
- return 1;
- }
-
- slprintf(job.owner, sizeof(job.owner) - 1, "%s", pw->pw_name);
-
- job.jobid = next_jobnum(printer);
- job.size = 666;
- job.submit_time = time(NULL);
-
- /* Store job entry in queue */
-
- slprintf(keystr, sizeof(keystr) - 1, "LPQ/%s", printer);
-
- value = tdb_fetch_bystring(tdb, keystr);
-
- if (value.dptr) {
-
- /* Add job to end of queue */
-
- queue.dptr = (unsigned char *)malloc(value.dsize + sizeof(struct vlp_job));
- if (!queue.dptr) return 1;
-
- memcpy(queue.dptr, value.dptr, value.dsize);
- memcpy(queue.dptr + value.dsize, &job, sizeof(struct vlp_job));
-
- queue.dsize = value.dsize + sizeof(struct vlp_job);
-
- tdb_store_bystring(tdb, keystr, queue, TDB_REPLACE);
-
- free(queue.dptr);
-
- } else {
-
- /* Create new queue */
- queue.dptr = (unsigned char *)&job;
- queue.dsize = sizeof(struct vlp_job);
-
- tdb_store_bystring(tdb, keystr, queue, TDB_REPLACE);
- }
-
- return 0;
-}
-
-/* Pause the queue */
-
-static int queuepause_command(int argc, char **argv)
-{
- char *printer;
-
- if (argc != 2) {
- printf("Usage: queuepause <printername>\n");
- return 1;
- }
-
- printer = argv[1];
- set_printer_status(printer, LPSTAT_STOPPED);
-
- return 0;
-}
-
-/* Resume the queue */
-
-static int queueresume_command(int argc, char **argv)
-{
- char *printer;
-
- if (argc != 2) {
- printf("Usage: queueresume <printername>\n");
- return 1;
- }
-
- printer = argv[1];
- set_printer_status(printer, LPSTAT_OK);
-
- return 0;
-}
-
-/* Pause a job */
-
-static int lppause_command(int argc, char **argv)
-{
- struct vlp_job *job_list;
- char *printer;
- int jobid, num_jobs, i;
-
- if (argc != 3) {
- printf("Usage: lppause <printername> <jobid>\n");
- return 1;
- }
-
- printer = argv[1];
- jobid = atoi(argv[2]);
-
- get_job_list(printer, &job_list, &num_jobs);
-
- for (i = 0; i < num_jobs; i++) {
- if (job_list[i].jobid == jobid) {
- job_list[i].status = LPQ_PAUSED;
- set_job_list(printer, job_list, num_jobs);
- return 0;
- }
- }
-
- return 1;
-}
-
-/* Resume a job */
-
-static int lpresume_command(int argc, char **argv)
-{
- struct vlp_job *job_list;
- char *printer;
- int jobid, num_jobs, i;
-
- if (argc != 3) {
- printf("Usage: lpresume <printername> <jobid>\n");
- return 1;
- }
-
- printer = argv[1];
- jobid = atoi(argv[2]);
-
- get_job_list(printer, &job_list, &num_jobs);
-
- for (i = 0; i < num_jobs; i++) {
- if (job_list[i].jobid == jobid) {
- job_list[i].status = LPQ_QUEUED;
- set_job_list(printer, job_list, num_jobs);
- return 0;
- }
- }
-
- return 1;
-}
-
-int main(int argc, char **argv)
-{
- /* Parameter check */
- const char *printdb_path = NULL;
-
- if (argc < 2) {
- usage();
- return 1;
- }
-
- if (strncmp(argv[1], "tdbfile", strlen("tdbfile")) != 0) {
- usage();
- return 1;
- }
-
- printdb_path = get_string_param(argv[1]);
- if (!printdb_path) {
- return 1;
- }
-
- if (!(tdb = tdb_open(printdb_path, 0, 0, O_RDWR | O_CREAT,
- 0666))) {
- printf("%s: unable to open %s\n", argv[0], printdb_path);
- return 1;
- }
-
- /* Ensure we are modes 666 */
-
- chmod(printdb_path, 0666);
-
- /* Do commands */
-
- if (strcmp(argv[2], "lpq") == 0) {
- return lpq_command(argc - 2, &argv[2]);
- }
-
- if (strcmp(argv[2], "lprm") == 0) {
- return lprm_command(argc - 2, &argv[2]);
- }
-
- if (strcmp(argv[2], "print") == 0) {
- return print_command(argc - 2, &argv[2]);
- }
-
- if (strcmp(argv[2], "queuepause") == 0) {
- return queuepause_command(argc - 2, &argv[2]);
- }
-
- if (strcmp(argv[2], "queueresume") == 0) {
- return queueresume_command(argc - 2, &argv[2]);
- }
-
- if (strcmp(argv[2], "lppause") == 0) {
- return lppause_command(argc - 2, &argv[2]);
- }
-
- if (strcmp(argv[2], "lpresume") == 0) {
- return lpresume_command(argc - 2, &argv[2]);
- }
-
- /* Unknown command */
-
- printf("%s: invalid command %s\n", argv[0], argv[1]);
- return 1;
-}