summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--WHATSNEW.txt62
-rw-r--r--packaging/RHEL-CTDB/samba.spec2
-rw-r--r--packaging/RHEL/makerpms.sh2
-rw-r--r--packaging/RHEL/samba.spec2
-rw-r--r--source3/VERSION2
-rw-r--r--source3/include/version.h4
-rw-r--r--source3/web/cgi.c29
-rw-r--r--source3/web/statuspage.c7
-rw-r--r--source3/web/swat.c175
-rw-r--r--source3/web/swat_proto.h6
10 files changed, 251 insertions, 40 deletions
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index f9b4a46c28..2f75a9ae43 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -1,3 +1,61 @@
+ ==============================
+ Release Notes for Samba 3.5.10
+ July 26, 2011
+ ==============================
+
+
+This is a security release in order to address
+CVE-2011-2522 (Cross-Site Request Forgery in SWAT) and
+CVE-2011-2694 (Cross-Site Scripting vulnerability in SWAT).
+
+
+o CVE-2011-2522:
+ The Samba Web Administration Tool (SWAT) in Samba versions
+ 3.0.x to 3.5.9 are affected by a cross-site request forgery.
+
+
+o CVE-2011-2694:
+ The Samba Web Administration Tool (SWAT) in Samba versions
+ 3.0.x to 3.5.9 are affected by a cross-site scripting
+ vulnerability.
+
+Please note that SWAT must be enabled in order for these
+vulnerabilities to be exploitable. By default, SWAT
+is *not* enabled on a Samba install.
+
+
+Changes since 3.5.9:
+--------------------
+
+
+o Kai Blin <kai@samba.org>
+ * BUG 8289: SWAT contains a cross-site scripting vulnerability.
+ * BUG 8290: CSRF vulnerability in SWAT.
+
+
+######################################################################
+Reporting bugs & Development Discussion
+#######################################
+
+Please discuss this release on the samba-technical mailing list or by
+joining the #samba-technical IRC channel on irc.freenode.net.
+
+If you do report problems then please try to send high quality
+feedback. If you don't provide vital information to help us track down
+the problem then you will probably be ignored. All bug reports should
+be filed under the Samba 3.5 product in the project's Bugzilla
+database (https://bugzilla.samba.org/).
+
+
+======================================================================
+== Our Code, Our Bugs, Our Responsibility.
+== The Samba Team
+======================================================================
+
+
+Release notes for older releases follow:
+----------------------------------------
+
=============================
Release Notes for Samba 3.5.9
June 14, 2011
@@ -142,8 +200,8 @@ database (https://bugzilla.samba.org/).
======================================================================
-Release notes for older releases follow:
-----------------------------------------
+----------------------------------------------------------------------
+
=============================
Release Notes for Samba 3.5.8
diff --git a/packaging/RHEL-CTDB/samba.spec b/packaging/RHEL-CTDB/samba.spec
index 08260fdcb0..efb7572b56 100644
--- a/packaging/RHEL-CTDB/samba.spec
+++ b/packaging/RHEL-CTDB/samba.spec
@@ -5,7 +5,7 @@ Summary: Samba SMB client and server
Vendor: Samba Team
Packager: Samba Team <samba@samba.org>
Name: samba
-Version: 3.5.9
+Version: 3.5.10
Release: 1GITHASH
Epoch: 0
License: GNU GPL version 3
diff --git a/packaging/RHEL/makerpms.sh b/packaging/RHEL/makerpms.sh
index 8e88629889..cb72f5205b 100644
--- a/packaging/RHEL/makerpms.sh
+++ b/packaging/RHEL/makerpms.sh
@@ -20,7 +20,7 @@ SRCDIR=`rpm --eval %_sourcedir`
USERID=`id -u`
GRPID=`id -g`
-VERSION='3.5.9'
+VERSION='3.5.10'
REVISION=''
SPECFILE="samba.spec"
RPMVER=`rpm --version | awk '{print $3}'`
diff --git a/packaging/RHEL/samba.spec b/packaging/RHEL/samba.spec
index 84ce96b2ba..3c70de6810 100644
--- a/packaging/RHEL/samba.spec
+++ b/packaging/RHEL/samba.spec
@@ -5,7 +5,7 @@ Summary: Samba SMB client and server
Vendor: Samba Team
Packager: Samba Team <samba@samba.org>
Name: samba
-Version: 3.5.9
+Version: 3.5.10
Release: 1
Epoch: 0
License: GNU GPL version 3
diff --git a/source3/VERSION b/source3/VERSION
index e79324d567..b6c1cd139d 100644
--- a/source3/VERSION
+++ b/source3/VERSION
@@ -25,7 +25,7 @@
########################################################
SAMBA_VERSION_MAJOR=3
SAMBA_VERSION_MINOR=5
-SAMBA_VERSION_RELEASE=9
+SAMBA_VERSION_RELEASE=10
########################################################
# Bug fix releases use a letter for the patch revision #
diff --git a/source3/include/version.h b/source3/include/version.h
index d6c53fe846..e1296ee0c2 100644
--- a/source3/include/version.h
+++ b/source3/include/version.h
@@ -1,8 +1,8 @@
/* Autogenerated by script/mkversion.sh */
#define SAMBA_VERSION_MAJOR 3
#define SAMBA_VERSION_MINOR 5
-#define SAMBA_VERSION_RELEASE 9
-#define SAMBA_VERSION_OFFICIAL_STRING "3.5.9"
+#define SAMBA_VERSION_RELEASE 10
+#define SAMBA_VERSION_OFFICIAL_STRING "3.5.10"
#ifdef SAMBA_VERSION_VENDOR_FUNCTION
# define SAMBA_VERSION_STRING SAMBA_VERSION_VENDOR_FUNCTION
#else /* SAMBA_VERSION_VENDOR_FUNCTION */
diff --git a/source3/web/cgi.c b/source3/web/cgi.c
index cf91b02175..0c8e9cbe55 100644
--- a/source3/web/cgi.c
+++ b/source3/web/cgi.c
@@ -19,6 +19,8 @@
#include "includes.h"
#include "web/swat_proto.h"
+#include "secrets.h"
+#include "../lib/util/util.h"
#define MAX_VARIABLES 10000
@@ -42,6 +44,7 @@ static char *query_string;
static const char *baseurl;
static char *pathinfo;
static char *C_user;
+static char *C_pass;
static bool inetd_server;
static bool got_request;
@@ -320,7 +323,23 @@ static void cgi_web_auth(void)
exit(0);
}
- setuid(0);
+ C_user = SMB_STRDUP(user);
+
+ if (!setuid(0)) {
+ C_pass = secrets_fetch_generic("root", "SWAT");
+ if (C_pass == NULL) {
+ char *tmp_pass = NULL;
+ tmp_pass = generate_random_str(talloc_tos(), 16);
+ if (tmp_pass == NULL) {
+ printf("%sFailed to create random nonce for "
+ "SWAT session\n<br>%s\n", head, tail);
+ exit(0);
+ }
+ secrets_store_generic("root", "SWAT", tmp_pass);
+ C_pass = SMB_STRDUP(tmp_pass);
+ TALLOC_FREE(tmp_pass);
+ }
+ }
setuid(pwd->pw_uid);
if (geteuid() != pwd->pw_uid || getuid() != pwd->pw_uid) {
printf("%sFailed to become user %s - uid=%d/%d<br>%s\n",
@@ -388,6 +407,7 @@ static bool cgi_handle_authorization(char *line)
/* Save the users name */
C_user = SMB_STRDUP(user);
+ C_pass = SMB_STRDUP(user_pass);
TALLOC_FREE(pass);
return True;
}
@@ -422,6 +442,13 @@ char *cgi_user_name(void)
return(C_user);
}
+/***************************************************************************
+return a ptr to the users password
+ ***************************************************************************/
+char *cgi_user_pass(void)
+{
+ return(C_pass);
+}
/***************************************************************************
handle a file download
diff --git a/source3/web/statuspage.c b/source3/web/statuspage.c
index 590be1dde2..cb5c57b6ee 100644
--- a/source3/web/statuspage.c
+++ b/source3/web/statuspage.c
@@ -247,9 +247,14 @@ void status_page(void)
int nr_running=0;
bool waitup = False;
TALLOC_CTX *ctx = talloc_stackframe();
+ const char form_name[] = "status";
smbd_pid = pid_to_procid(pidfile_pid("smbd"));
+ if (!verify_xsrf_token(form_name)) {
+ goto output_page;
+ }
+
if (cgi_variable("smbd_restart") || cgi_variable("all_restart")) {
stop_smbd();
start_smbd();
@@ -326,9 +331,11 @@ void status_page(void)
initPid2Machine ();
+output_page:
printf("<H2>%s</H2>\n", _("Server Status"));
printf("<FORM method=post>\n");
+ print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
if (!autorefresh) {
printf("<input type=submit value=\"%s\" name=\"autorefresh\">\n", _("Auto Refresh"));
diff --git a/source3/web/swat.c b/source3/web/swat.c
index baffa44bae..3a88986f38 100644
--- a/source3/web/swat.c
+++ b/source3/web/swat.c
@@ -29,6 +29,7 @@
#include "includes.h"
#include "web/swat_proto.h"
+#include "../lib/crypto/md5.h"
static int demo_mode = False;
static int passwd_only = False;
@@ -50,6 +51,9 @@ static int iNumNonAutoPrintServices = 0;
#define DISABLE_USER_FLAG "disable_user_flag"
#define ENABLE_USER_FLAG "enable_user_flag"
#define RHOST "remote_host"
+#define XSRF_TOKEN "xsrf"
+#define XSRF_TIME "xsrf_time"
+#define XSRF_TIMEOUT 300
#define _(x) lang_msg_rotate(talloc_tos(),x)
@@ -138,6 +142,76 @@ static char *make_parm_name(const char *label)
return parmname;
}
+void get_xsrf_token(const char *username, const char *pass,
+ const char *formname, time_t xsrf_time, char token_str[33])
+{
+ struct MD5Context md5_ctx;
+ uint8_t token[16];
+ int i;
+
+ token_str[0] = '\0';
+ ZERO_STRUCT(md5_ctx);
+ MD5Init(&md5_ctx);
+
+ MD5Update(&md5_ctx, (uint8_t *)formname, strlen(formname));
+ MD5Update(&md5_ctx, (uint8_t *)&xsrf_time, sizeof(time_t));
+ if (username != NULL) {
+ MD5Update(&md5_ctx, (uint8_t *)username, strlen(username));
+ }
+ if (pass != NULL) {
+ MD5Update(&md5_ctx, (uint8_t *)pass, strlen(pass));
+ }
+
+ MD5Final(token, &md5_ctx);
+
+ for(i = 0; i < sizeof(token); i++) {
+ char tmp[3];
+
+ snprintf(tmp, sizeof(tmp), "%02x", token[i]);
+ strncat(token_str, tmp, sizeof(tmp));
+ }
+}
+
+void print_xsrf_token(const char *username, const char *pass,
+ const char *formname)
+{
+ char token[33];
+ time_t xsrf_time = time(NULL);
+
+ get_xsrf_token(username, pass, formname, xsrf_time, token);
+ printf("<input type=\"hidden\" name=\"%s\" value=\"%s\">\n",
+ XSRF_TOKEN, token);
+ printf("<input type=\"hidden\" name=\"%s\" value=\"%lld\">\n",
+ XSRF_TIME, (long long int)xsrf_time);
+}
+
+bool verify_xsrf_token(const char *formname)
+{
+ char expected[33];
+ const char *username = cgi_user_name();
+ const char *pass = cgi_user_pass();
+ const char *token = cgi_variable_nonull(XSRF_TOKEN);
+ const char *time_str = cgi_variable_nonull(XSRF_TIME);
+ time_t xsrf_time = 0;
+ time_t now = time(NULL);
+
+ if (sizeof(time_t) == sizeof(int)) {
+ xsrf_time = atoi(time_str);
+ } else if (sizeof(time_t) == sizeof(long)) {
+ xsrf_time = atol(time_str);
+ } else if (sizeof(time_t) == sizeof(long long)) {
+ xsrf_time = atoll(time_str);
+ }
+
+ if (abs(now - xsrf_time) > XSRF_TIMEOUT) {
+ return false;
+ }
+
+ get_xsrf_token(username, pass, formname, xsrf_time, expected);
+ return (strncmp(expected, token, sizeof(expected)) == 0);
+}
+
+
/****************************************************************************
include a lump of html in a page
****************************************************************************/
@@ -611,13 +685,20 @@ static void welcome_page(void)
static void viewconfig_page(void)
{
int full_view=0;
+ const char form_name[] = "viewconfig";
+
+ if (!verify_xsrf_token(form_name)) {
+ goto output_page;
+ }
if (cgi_variable("full_view")) {
full_view = 1;
}
+output_page:
printf("<H2>%s</H2>\n", _("Current Config"));
printf("<form method=post>\n");
+ print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
if (full_view) {
printf("<input type=submit name=\"normal_view\" value=\"%s\">\n", _("Normal View"));
@@ -637,18 +718,25 @@ static void viewconfig_page(void)
static void wizard_params_page(void)
{
unsigned int parm_filter = FLAG_WIZARD;
+ const char form_name[] = "wizard_params";
/* Here we first set and commit all the parameters that were selected
in the previous screen. */
printf("<H2>%s</H2>\n", _("Wizard Parameter Edit Page"));
+ if (!verify_xsrf_token(form_name)) {
+ goto output_page;
+ }
+
if (cgi_variable("Commit")) {
commit_parameters(GLOBAL_SECTION_SNUM);
save_reload(-1);
}
+output_page:
printf("<form name=\"swatform\" method=post action=wizard_params>\n");
+ print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
if (have_write_access) {
printf("<input type=submit name=\"Commit\" value=\"Commit Changes\">\n");
@@ -684,6 +772,11 @@ static void wizard_page(void)
int have_home = -1;
int HomeExpo = 0;
int SerType = 0;
+ const char form_name[] = "wizard";
+
+ if (!verify_xsrf_token(form_name)) {
+ goto output_page;
+ }
if (cgi_variable("Rewrite")) {
(void) rewritecfg_file();
@@ -774,10 +867,12 @@ static void wizard_page(void)
winstype = 3;
role = lp_server_role();
-
+
+output_page:
/* Here we go ... */
printf("<H2>%s</H2>\n", _("Samba Configuration Wizard"));
printf("<form method=post action=wizard>\n");
+ print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
if (have_write_access) {
printf("%s\n", _("The \"Rewrite smb.conf file\" button will clear the smb.conf file of all default values and of comments."));
@@ -846,9 +941,14 @@ static void globals_page(void)
{
unsigned int parm_filter = FLAG_BASIC;
int mode = 0;
+ const char form_name[] = "globals";
printf("<H2>%s</H2>\n", _("Global Parameters"));
+ if (!verify_xsrf_token(form_name)) {
+ goto output_page;
+ }
+
if (cgi_variable("Commit")) {
commit_parameters(GLOBAL_SECTION_SNUM);
save_reload(-1);
@@ -861,7 +961,9 @@ static void globals_page(void)
if ( cgi_variable("AdvMode"))
mode = 1;
+output_page:
printf("<form name=\"swatform\" method=post action=globals>\n");
+ print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
ViewModeBoxes( mode );
switch ( mode ) {
@@ -901,11 +1003,17 @@ static void shares_page(void)
int mode = 0;
unsigned int parm_filter = FLAG_BASIC;
size_t converted_size;
+ const char form_name[] = "shares";
+
+ printf("<H2>%s</H2>\n", _("Share Parameters"));
+
+ if (!verify_xsrf_token(form_name)) {
+ goto output_page;
+ }
if (share)
snum = lp_servicenumber(share);
- printf("<H2>%s</H2>\n", _("Share Parameters"));
if (cgi_variable("Commit") && snum >= 0) {
commit_parameters(snum);
@@ -931,10 +1039,6 @@ static void shares_page(void)
}
}
- printf("<FORM name=\"swatform\" method=post>\n");
-
- printf("<table>\n");
-
if ( cgi_variable("ViewMode") )
mode = atoi(cgi_variable_nonull("ViewMode"));
if ( cgi_variable("BasicMode"))
@@ -942,6 +1046,12 @@ static void shares_page(void)
if ( cgi_variable("AdvMode"))
mode = 1;
+output_page:
+ printf("<FORM name=\"swatform\" method=post>\n");
+ print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
+
+ printf("<table>\n");
+
ViewModeBoxes( mode );
switch ( mode ) {
case 0:
@@ -1121,11 +1231,9 @@ static void chg_passwd(void)
if(cgi_variable(CHG_S_PASSWD_FLAG)) {
printf("<p>");
if (rslt == True) {
- printf(_(" The passwd for '%s' has been changed."), cgi_variable_nonull(SWAT_USER));
- printf("\n");
+ printf("%s\n", _(" The passwd has been changed."));
} else {
- printf(_(" The passwd for '%s' has NOT been changed."), cgi_variable_nonull(SWAT_USER));
- printf("\n");
+ printf("%s\n", _(" The passwd has NOT been changed."));
}
}
@@ -1138,20 +1246,15 @@ static void chg_passwd(void)
static void passwd_page(void)
{
const char *new_name = cgi_user_name();
-
- /*
- * After the first time through here be nice. If the user
- * changed the User box text to another users name, remember it.
- */
- if (cgi_variable(SWAT_USER)) {
- new_name = cgi_variable_nonull(SWAT_USER);
- }
+ const char passwd_form[] = "passwd";
+ const char rpasswd_form[] = "rpasswd";
if (!new_name) new_name = "";
printf("<H2>%s</H2>\n", _("Server Password Management"));
printf("<FORM name=\"swatform\" method=post>\n");
+ print_xsrf_token(cgi_user_name(), cgi_user_pass(), passwd_form);
printf("<table>\n");
@@ -1191,14 +1294,16 @@ static void passwd_page(void)
* Do some work if change, add, disable or enable was
* requested. It could be this is the first time through this
* code, so there isn't anything to do. */
- if ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
- (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG))) {
+ if (verify_xsrf_token(passwd_form) &&
+ ((cgi_variable(CHG_S_PASSWD_FLAG)) || (cgi_variable(ADD_USER_FLAG)) || (cgi_variable(DELETE_USER_FLAG)) ||
+ (cgi_variable(DISABLE_USER_FLAG)) || (cgi_variable(ENABLE_USER_FLAG)))) {
chg_passwd();
}
printf("<H2>%s</H2>\n", _("Client/Server Password Management"));
printf("<FORM name=\"swatform\" method=post>\n");
+ print_xsrf_token(cgi_user_name(), cgi_user_pass(), rpasswd_form);
printf("<table>\n");
@@ -1231,7 +1336,7 @@ static void passwd_page(void)
* password somewhere other than the server. It could be this
* is the first time through this code, so there isn't
* anything to do. */
- if (cgi_variable(CHG_R_PASSWD_FLAG)) {
+ if (verify_xsrf_token(passwd_form) && cgi_variable(CHG_R_PASSWD_FLAG)) {
chg_passwd();
}
@@ -1248,18 +1353,15 @@ static void printers_page(void)
int i;
int mode = 0;
unsigned int parm_filter = FLAG_BASIC;
+ const char form_name[] = "printers";
+
+ if (!verify_xsrf_token(form_name)) {
+ goto output_page;
+ }
if (share)
snum = lp_servicenumber(share);
- printf("<H2>%s</H2>\n", _("Printer Parameters"));
-
- printf("<H3>%s</H3>\n", _("Important Note:"));
- printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
- printf("%s",_("are autoloaded printers from "));
- printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
- printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
-
if (cgi_variable("Commit") && snum >= 0) {
commit_parameters(snum);
if (snum >= iNumNonAutoPrintServices)
@@ -1288,8 +1390,6 @@ static void printers_page(void)
}
}
- printf("<FORM name=\"swatform\" method=post>\n");
-
if ( cgi_variable("ViewMode") )
mode = atoi(cgi_variable_nonull("ViewMode"));
if ( cgi_variable("BasicMode"))
@@ -1297,6 +1397,19 @@ static void printers_page(void)
if ( cgi_variable("AdvMode"))
mode = 1;
+output_page:
+ printf("<H2>%s</H2>\n", _("Printer Parameters"));
+
+ printf("<H3>%s</H3>\n", _("Important Note:"));
+ printf("%s",_("Printer names marked with [*] in the Choose Printer drop-down box "));
+ printf("%s",_("are autoloaded printers from "));
+ printf("<A HREF=\"/swat/help/smb.conf.5.html#printcapname\" target=\"docs\">%s</A>\n", _("Printcap Name"));
+ printf("%s\n", _("Attempting to delete these printers from SWAT will have no effect."));
+
+
+ printf("<FORM name=\"swatform\" method=post>\n");
+ print_xsrf_token(cgi_user_name(), cgi_user_pass(), form_name);
+
ViewModeBoxes( mode );
switch ( mode ) {
case 0:
diff --git a/source3/web/swat_proto.h b/source3/web/swat_proto.h
index 0f84e4f4ce..424a3af545 100644
--- a/source3/web/swat_proto.h
+++ b/source3/web/swat_proto.h
@@ -31,6 +31,7 @@ const char *cgi_variable(const char *name);
const char *cgi_variable_nonull(const char *name);
bool am_root(void);
char *cgi_user_name(void);
+char *cgi_user_pass(void);
void cgi_setup(const char *rootdir, int auth_required);
const char *cgi_baseurl(void);
const char *cgi_pathinfo(void);
@@ -66,5 +67,10 @@ void status_page(void);
/* The following definitions come from web/swat.c */
const char *lang_msg_rotate(TALLOC_CTX *ctx, const char *msgid);
+void get_xsrf_token(const char *username, const char *pass,
+ const char *formname, time_t xsrf_time, char token_str[33]);
+void print_xsrf_token(const char *username, const char *pass,
+ const char *formname);
+bool verify_xsrf_token(const char *formname);
#endif /* _SWAT_PROTO_H_ */