diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/lib/charcnv.c | 25 | ||||
-rw-r--r-- | source3/modules/onefs_open.c | 37 | ||||
-rw-r--r-- | source3/passdb/pdb_tdb.c | 60 | ||||
-rw-r--r-- | source3/rpc_server/srv_lsa_nt.c | 8 | ||||
-rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 243 |
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; } |