summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-rw-r--r--source3/lib/charcnv.c25
-rw-r--r--source3/modules/onefs_open.c37
-rw-r--r--source3/passdb/pdb_tdb.c60
-rw-r--r--source3/rpc_server/srv_lsa_nt.c8
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c243
5 files changed, 334 insertions, 39 deletions
diff --git a/source3/lib/charcnv.c b/source3/lib/charcnv.c
index c3b345142f..03b32c13d4 100644
--- a/source3/lib/charcnv.c
+++ b/source3/lib/charcnv.c
@@ -242,7 +242,7 @@ static size_t convert_string_internal(charset_t from, charset_t to,
DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
if (allow_bad_conv)
goto use_as_is;
- break;
+ return (size_t)-1;
case E2BIG:
reason="No more room";
if (!conv_silent) {
@@ -263,11 +263,12 @@ static size_t convert_string_internal(charset_t from, charset_t to,
DEBUG(3,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
if (allow_bad_conv)
goto use_as_is;
- break;
+
+ return (size_t)-1;
default:
if (!conv_silent)
DEBUG(0,("convert_string_internal: Conversion error: %s(%s)\n",reason,inbuf));
- break;
+ return (size_t)-1;
}
/* smb_panic(reason); */
}
@@ -412,7 +413,11 @@ size_t convert_string(charset_t from, charset_t to,
#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
goto general_case;
#else
- return retval + convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
+ size_t ret = convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
+ if (ret == (size_t)-1) {
+ return ret;
+ }
+ return retval + ret;
#endif
}
}
@@ -448,7 +453,11 @@ size_t convert_string(charset_t from, charset_t to,
#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
goto general_case;
#else
- return retval + convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
+ size_t ret = convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
+ if (ret == (size_t)-1) {
+ return ret;
+ }
+ return retval + ret;
#endif
}
}
@@ -484,7 +493,11 @@ size_t convert_string(charset_t from, charset_t to,
#ifdef BROKEN_UNICODE_COMPOSE_CHARACTERS
goto general_case;
#else
- return retval + convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
+ size_t ret = convert_string_internal(from, to, p, slen, q, dlen, allow_bad_conv);
+ if (ret == (size_t)-1) {
+ return ret;
+ }
+ return retval + ret;
#endif
}
}
diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c
index d628443ef9..f315b34c8b 100644
--- a/source3/modules/onefs_open.c
+++ b/source3/modules/onefs_open.c
@@ -199,23 +199,6 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
if ((conn->fs_capabilities & FILE_NAMED_STREAMS) && stream != NULL) {
SMB_ASSERT(fsp->base_fsp);
- /*
- * We have never seen an oplock taken on a stream, and our
- * current implementation doesn't support it. If a request is
- * seen, log a loud error message and ignore the requested
- * oplock.
- */
- if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
- NO_OPLOCK) {
- DEBUG(0, ("Oplock(%d) being requested on a stream! "
- "Ignoring oplock request: base=%s, "
- "stream=%s\n",
- oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
- base, stream));
- /* Recover by requesting NO_OPLOCK instead. */
- oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
- }
-
DEBUG(10,("Opening a stream: base=%s(%d), stream=%s\n",
base, fsp->base_fsp->fh->fd, stream));
@@ -522,10 +505,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
*
* 1. Open the base file of a stream: Always done stat-only
*
- * 2. Open the stream: Oplocks are disallowed on streams, so an
- * oplock will never be contended.
- *
- * 3. open_file_fchmod(), which is called from 3 places:
+ * 2. open_file_fchmod(), which is called from 3 places:
* A. try_chown: Posix acls only. Never called on onefs.
* B. set_ea_dos_attributes: Can't be called from onefs, because
* SMB_VFS_SETXATTR return ENOSYS.
@@ -1773,6 +1753,21 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
"failed: %s\n", base, nt_errstr(status)));
goto fail;
}
+
+ /*
+ * Testing against windows xp/2003/vista shows that oplocks
+ * can actually be requested and granted on streams (see the
+ * RAW-OPLOCK-STREAM1 smbtorture test).
+ */
+ if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
+ NO_OPLOCK) {
+ DEBUG(5, ("Oplock(%d) being requested on a stream! "
+ "Ignoring oplock request: fname=%s\n",
+ oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
+ fname));
+ /* Request NO_OPLOCK instead. */
+ oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
+ }
}
/* Covert generic bits in the security descriptor. */
diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c
index 6c49eb1dc2..dd6e678c99 100644
--- a/source3/passdb/pdb_tdb.c
+++ b/source3/passdb/pdb_tdb.c
@@ -817,12 +817,17 @@ static bool tdb_update_ridrec_only( struct samu* newpwd, int flag )
static bool tdb_update_sam(struct pdb_methods *my_methods, struct samu* newpwd,
int flag)
{
- if (!pdb_get_user_rid(newpwd)) {
+ uint32_t oldrid;
+ uint32_t newrid;
+
+ if (!(newrid = pdb_get_user_rid(newpwd))) {
DEBUG(0,("tdb_update_sam: struct samu (%s) with no RID!\n",
pdb_get_username(newpwd)));
return False;
}
+ oldrid = newrid;
+
/* open the database */
if ( !tdbsam_open( tdbsam_filename ) ) {
@@ -835,11 +840,60 @@ static bool tdb_update_sam(struct pdb_methods *my_methods, struct samu* newpwd,
return false;
}
- if (!tdb_update_samacct_only(newpwd, flag)
- || !tdb_update_ridrec_only(newpwd, flag)) {
+ /* If we are updating, we may be changing this users RID. Retrieve the old RID
+ so we can check. */
+
+ if (flag == TDB_MODIFY) {
+ struct samu *account = samu_new(talloc_tos());
+ if (account == NULL) {
+ DEBUG(0,("tdb_update_sam: samu_new() failed\n"));
+ goto cancel;
+ }
+ if (!NT_STATUS_IS_OK(tdbsam_getsampwnam(my_methods, account, pdb_get_username(newpwd)))) {
+ DEBUG(0,("tdb_update_sam: tdbsam_getsampwnam() for %s failed\n",
+ pdb_get_username(newpwd)));
+ TALLOC_FREE(account);
+ goto cancel;
+ }
+ if (!(oldrid = pdb_get_user_rid(account))) {
+ DEBUG(0,("tdb_update_sam: pdb_get_user_rid() failed\n"));
+ TALLOC_FREE(account);
+ goto cancel;
+ }
+ TALLOC_FREE(account);
+ }
+
+ /* Update the new samu entry. */
+ if (!tdb_update_samacct_only(newpwd, flag)) {
goto cancel;
}
+ /* Now take care of the case where the RID changed. We need
+ * to delete the old RID key and add the new. */
+
+ if (flag == TDB_MODIFY && newrid != oldrid) {
+ fstring keystr;
+
+ /* Delete old RID key */
+ DEBUG(10, ("tdb_update_sam: Deleting key for RID %u\n", oldrid));
+ slprintf(keystr, sizeof(keystr) - 1, "%s%.8x", RIDPREFIX, oldrid);
+ if (!NT_STATUS_IS_OK(dbwrap_delete_bystring(db_sam, keystr))) {
+ DEBUG(0, ("tdb_update_sam: Can't delete %s\n", keystr));
+ goto cancel;
+ }
+ /* Insert new RID key */
+ DEBUG(10, ("tdb_update_sam: Inserting key for RID %u\n", newrid));
+ if (!tdb_update_ridrec_only(newpwd, TDB_INSERT)) {
+ goto cancel;
+ }
+ } else {
+ DEBUG(10, ("tdb_update_sam: %s key for RID %u\n",
+ flag == TDB_MODIFY ? "Updating" : "Inserting", newrid));
+ if (!tdb_update_ridrec_only(newpwd, flag)) {
+ goto cancel;
+ }
+ }
+
if (db_sam->transaction_commit(db_sam) != 0) {
DEBUG(0, ("Could not commit transaction\n"));
return false;
diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c
index 5fdcaf2d4a..0ce2b40f65 100644
--- a/source3/rpc_server/srv_lsa_nt.c
+++ b/source3/rpc_server/srv_lsa_nt.c
@@ -648,14 +648,14 @@ NTSTATUS _lsa_QueryInfoPolicy(pipes_struct *p,
* only a BDC is a backup controller
* of the domain, it controls.
*/
- info->role.role = 2;
+ info->role.role = LSA_ROLE_BACKUP;
break;
default:
/*
* any other role is a primary
* of the domain, it controls.
*/
- info->role.role = 3;
+ info->role.role = LSA_ROLE_PRIMARY;
break;
}
break;
@@ -1434,14 +1434,14 @@ NTSTATUS _lsa_EnumAccounts(pipes_struct *p,
sids = TALLOC_ZERO_ARRAY(p->mem_ctx, struct lsa_SidPtr,
num_entries - *r->in.resume_handle);
if (!sids) {
- SAFE_FREE(sid_list);
+ talloc_free(sid_list);
return NT_STATUS_NO_MEMORY;
}
for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
sids[j].sid = sid_dup_talloc(p->mem_ctx, &sid_list[i]);
if (!sids[j].sid) {
- SAFE_FREE(sid_list);
+ talloc_free(sid_list);
return NT_STATUS_NO_MEMORY;
}
}
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 15c137a88c..7bb0571042 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -4890,6 +4890,174 @@ static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
}
/********************************************************************
+ ********************************************************************/
+
+static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverFileInfo *r,
+ const char *cservername,
+ const char *file_name,
+ enum spoolss_DriverFileType file_type,
+ uint32_t file_version)
+{
+ r->file_name = talloc_asprintf(mem_ctx, "\\\\%s%s",
+ cservername, file_name);
+ W_ERROR_HAVE_NO_MEMORY(r->file_name);
+ r->file_type = file_type;
+ r->file_version = file_version;
+
+ return WERR_OK;
+}
+
+/********************************************************************
+ ********************************************************************/
+
+static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
+ const NT_PRINTER_DRIVER_INFO_LEVEL *driver,
+ const char *cservername,
+ struct spoolss_DriverFileInfo **info_p,
+ uint32_t *count_p)
+{
+ struct spoolss_DriverFileInfo *info = NULL;
+ uint32_t count = 0;
+ WERROR result;
+ uint32_t i;
+
+ *info_p = NULL;
+ *count_p = 0;
+
+ if (strlen(driver->info_3->driverpath)) {
+ info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
+ struct spoolss_DriverFileInfo,
+ count + 1);
+ W_ERROR_HAVE_NO_MEMORY(info);
+ result = fill_spoolss_DriverFileInfo(info,
+ &info[count],
+ cservername,
+ driver->info_3->driverpath,
+ SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
+ 0);
+ W_ERROR_NOT_OK_RETURN(result);
+ count++;
+ }
+
+ if (strlen(driver->info_3->configfile)) {
+ info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
+ struct spoolss_DriverFileInfo,
+ count + 1);
+ W_ERROR_HAVE_NO_MEMORY(info);
+ result = fill_spoolss_DriverFileInfo(info,
+ &info[count],
+ cservername,
+ driver->info_3->configfile,
+ SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
+ 0);
+ W_ERROR_NOT_OK_RETURN(result);
+ count++;
+ }
+
+ if (strlen(driver->info_3->datafile)) {
+ info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
+ struct spoolss_DriverFileInfo,
+ count + 1);
+ W_ERROR_HAVE_NO_MEMORY(info);
+ result = fill_spoolss_DriverFileInfo(info,
+ &info[count],
+ cservername,
+ driver->info_3->datafile,
+ SPOOLSS_DRIVER_FILE_TYPE_DATA,
+ 0);
+ W_ERROR_NOT_OK_RETURN(result);
+ count++;
+ }
+
+ if (strlen(driver->info_3->helpfile)) {
+ info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
+ struct spoolss_DriverFileInfo,
+ count + 1);
+ W_ERROR_HAVE_NO_MEMORY(info);
+ result = fill_spoolss_DriverFileInfo(info,
+ &info[count],
+ cservername,
+ driver->info_3->helpfile,
+ SPOOLSS_DRIVER_FILE_TYPE_HELP,
+ 0);
+ W_ERROR_NOT_OK_RETURN(result);
+ count++;
+ }
+
+ for (i=0; driver->info_3->dependentfiles[i][0] != '\0'; i++) {
+ info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
+ struct spoolss_DriverFileInfo,
+ count + 1);
+ W_ERROR_HAVE_NO_MEMORY(info);
+ result = fill_spoolss_DriverFileInfo(info,
+ &info[count],
+ cservername,
+ driver->info_3->dependentfiles[i],
+ SPOOLSS_DRIVER_FILE_TYPE_OTHER,
+ 0);
+ W_ERROR_NOT_OK_RETURN(result);
+ count++;
+ }
+
+ *info_p = info;
+ *count_p = count;
+
+ return WERR_OK;
+}
+
+/********************************************************************
+ * fill a spoolss_DriverInfo101 sttruct
+ ********************************************************************/
+
+static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverInfo101 *r,
+ const NT_PRINTER_DRIVER_INFO_LEVEL *driver,
+ const char *servername)
+{
+ const char *cservername = canon_servername(servername);
+ WERROR result;
+
+ r->version = driver->info_3->cversion;
+
+ r->driver_name = talloc_strdup(mem_ctx, driver->info_3->name);
+ W_ERROR_HAVE_NO_MEMORY(r->driver_name);
+ r->architecture = talloc_strdup(mem_ctx, driver->info_3->environment);
+ W_ERROR_HAVE_NO_MEMORY(r->architecture);
+
+ result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
+ cservername,
+ &r->file_info,
+ &r->file_count);
+ if (!W_ERROR_IS_OK(result)) {
+ return result;
+ }
+
+ r->monitor_name = talloc_strdup(mem_ctx, driver->info_3->monitorname);
+ W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
+
+ r->default_datatype = talloc_strdup(mem_ctx, driver->info_3->defaultdatatype);
+ W_ERROR_HAVE_NO_MEMORY(r->default_datatype);
+
+ r->previous_names = string_array_from_driver_info(mem_ctx,
+ NULL,
+ cservername);
+ r->driver_date = 0;
+ r->driver_version = 0;
+
+ r->manufacturer_name = talloc_strdup(mem_ctx, "");
+ W_ERROR_HAVE_NO_MEMORY(r->manufacturer_name);
+ r->manufacturer_url = talloc_strdup(mem_ctx, "");
+ W_ERROR_HAVE_NO_MEMORY(r->manufacturer_url);
+ r->hardware_id = talloc_strdup(mem_ctx, "");
+ W_ERROR_HAVE_NO_MEMORY(r->hardware_id);
+ r->provider = talloc_strdup(mem_ctx, "");
+ W_ERROR_HAVE_NO_MEMORY(r->provider);
+
+ return WERR_OK;
+}
+
+/********************************************************************
* construct_printer_driver_info_1
********************************************************************/
@@ -5077,6 +5245,69 @@ static WERROR construct_printer_driver_info_6(TALLOC_CTX *mem_ctx,
return status;
}
+/********************************************************************
+ * construct_printer_info_101
+ * fill a printer_info_101 struct
+ ********************************************************************/
+
+static WERROR construct_printer_driver_info_101(TALLOC_CTX *mem_ctx,
+ struct spoolss_DriverInfo101 *r,
+ int snum,
+ const char *servername,
+ const char *architecture,
+ uint32_t version)
+{
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ NT_PRINTER_DRIVER_INFO_LEVEL driver;
+ WERROR result;
+
+ ZERO_STRUCT(driver);
+
+ result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
+
+ DEBUG(8,("construct_printer_driver_info_101: status: %s\n",
+ win_errstr(result)));
+
+ if (!W_ERROR_IS_OK(result)) {
+ return WERR_INVALID_PRINTER_NAME;
+ }
+
+ result = get_a_printer_driver(&driver, 3, printer->info_2->drivername,
+ architecture, version);
+
+ DEBUG(8,("construct_printer_driver_info_101: status: %s\n",
+ win_errstr(result)));
+
+ if (!W_ERROR_IS_OK(result)) {
+ /*
+ * Is this a W2k client ?
+ */
+
+ if (version < 3) {
+ free_a_printer(&printer, 2);
+ return WERR_UNKNOWN_PRINTER_DRIVER;
+ }
+
+ /* Yes - try again with a WinNT driver. */
+ version = 2;
+ result = get_a_printer_driver(&driver, 3, printer->info_2->drivername,
+ architecture, version);
+ DEBUG(8,("construct_printer_driver_info_6: status: %s\n",
+ win_errstr(result)));
+ if (!W_ERROR_IS_OK(result)) {
+ free_a_printer(&printer, 2);
+ return WERR_UNKNOWN_PRINTER_DRIVER;
+ }
+ }
+
+ result = fill_printer_driver_info101(mem_ctx, r, &driver, servername);
+
+ free_a_printer(&printer, 2);
+ free_a_printer_driver(driver, 3);
+
+ return result;
+}
+
/****************************************************************
_spoolss_GetPrinterDriver2
****************************************************************/
@@ -5146,13 +5377,15 @@ WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
r->in.architecture,
r->in.client_major_version);
break;
- default:
-#if 0 /* JERRY */
case 101:
- /* apparently this call is the equivalent of
- EnumPrinterDataEx() for the DsDriver key */
+ result = construct_printer_driver_info_101(p->mem_ctx,
+ &r->out.info->info101,
+ snum,
+ servername,
+ r->in.architecture,
+ r->in.client_major_version);
break;
-#endif
+ default:
result = WERR_UNKNOWN_LEVEL;
break;
}