summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/debug.h132
-rw-r--r--source3/include/proto.h7
-rw-r--r--source3/lib/debug.c128
-rw-r--r--source3/lib/messages.c3
-rw-r--r--source3/lib/msrpc_use.c4
-rw-r--r--source3/param/loadparm.c23
-rw-r--r--source3/printing/nt_printing.c15
-rw-r--r--source3/rpc_parse/parse_spoolss.c21
-rw-r--r--source3/smbd/nttrans.c11
-rw-r--r--source3/smbd/posix_acls.c2
-rw-r--r--source3/smbd/process.c29
-rw-r--r--source3/smbd/reply.c10
-rw-r--r--source3/smbd/server.c17
-rw-r--r--source3/utils/smbcontrol.c51
14 files changed, 378 insertions, 75 deletions
diff --git a/source3/include/debug.h b/source3/include/debug.h
index 3130bc379d..d2c3b1d37e 100644
--- a/source3/include/debug.h
+++ b/source3/include/debug.h
@@ -66,38 +66,124 @@ BOOL dbgtext();
#define FUNCTION_MACRO ("")
#endif
-/* Debugging macros.
- * DEBUGLVL() - If level is <= the system-wide DEBUGLEVEL then generate a
- * header using the default macros for file, line, and
- * function name.
- * Returns True if the debug level was <= DEBUGLEVEL.
- * Example usage:
- * if( DEBUGLVL( 2 ) )
- * dbgtext( "Some text.\n" );
- * DEBUG() - Good old DEBUG(). Each call to DEBUG() will generate a new
- * header *unless* the previous debug output was unterminated
- * (i.e., no '\n'). See debug.c:dbghdr() for more info.
- * Example usage:
- * DEBUG( 2, ("Some text.\n") );
- * DEBUGADD() - If level <= DEBUGLEVEL, then the text is appended to the
- * current message (i.e., no header).
- * Usage:
- * DEBUGADD( 2, ("Some additional text.\n") );
+/*
+ * Redefine DEBUGLEVEL because so we don't have to change every source file
+ * that *unnecessarily* references it. Source files neeed not extern reference
+ * DEBUGLEVEL, as it's extern in includes.h (which all source files include).
+ * Eventually, all these references should be removed, and all references to
+ * DEBUGLEVEL should be references to DEBUGLEVEL_CLASS[DBGC_ALL]. This could
+ * still be through a macro still called DEBUGLEVEL. This cannot be done now
+ * because some references would expand incorrectly.
+ */
+#define DEBUGLEVEL *debug_level
+
+
+/*
+ * Define all new debug classes here. A class is represented by an entry in
+ * the DEBUGLEVEL_CLASS array. Index zero of this arrray is equivalent to the
+ * old DEBUGLEVEL. Any source file that does NOT add the following lines:
+ *
+ * #undef DBGC_CLASS
+ * #define DBGC_CLASS DBGC_<your class name here>
+ *
+ * at the start of the file (after #include "includes.h") will default to
+ * using index zero, so it will behaive just like it always has.
+ */
+#define DBGC_CLASS 0 /* override as shown above */
+#define DBGC_ALL 0 /* index equivalent to DEBUGLEVEL */
+
+#define DBGC_TDB 1
+#define DBGC_PRINTDRIVERS 2
+#define DBGC_LANMAN 3
+
+#define DBGC_LAST 4 /* MUST be last class value + 1 */
+
+
+extern int DEBUGLEVEL_CLASS[DBGC_LAST];
+
+
+/* Debugging macros
+ *
+ * DEBUGLVL()
+ * If the 'file specific' debug class level >= level OR the system-wide
+ * DEBUGLEVEL (synomym for DEBUGLEVEL_CLASS[ DBGC_ALL ]) >= level then
+ * generate a header using the default macros for file, line, and
+ * function name. Returns True if the debug level was <= DEBUGLEVEL.
+ *
+ * Example: if( DEBUGLVL( 2 ) ) dbgtext( "Some text.\n" );
+ *
+ * DEBUGLVLC()
+ * If the 'macro specified' debug class level >= level OR the system-wide
+ * DEBUGLEVEL (synomym for DEBUGLEVEL_CLASS[ DBGC_ALL ]) >= level then
+ * generate a header using the default macros for file, line, and
+ * function name. Returns True if the debug level was <= DEBUGLEVEL.
+ *
+ * Example: if( DEBUGLVL( DBGC_TDB, 2 ) ) dbgtext( "Some text.\n" );
+ *
+ * DEBUG()
+ * If the 'file specific' debug class level >= level OR the system-wide
+ * DEBUGLEVEL (synomym for DEBUGLEVEL_CLASS[ DBGC_ALL ]) >= level then
+ * generate a header using the default macros for file, line, and
+ * function name. Each call to DEBUG() generates a new header *unless* the
+ * previous debug output was unterminated (i.e. no '\n').
+ * See debug.c:dbghdr() for more info.
+ *
+ * Example: DEBUG( 2, ("Some text and a valu %d.\n", value) );
+ *
+ * DEBUGC()
+ * If the 'macro specified' debug class level >= level OR the system-wide
+ * DEBUGLEVEL (synomym for DEBUGLEVEL_CLASS[ DBGC_ALL ]) >= level then
+ * generate a header using the default macros for file, line, and
+ * function name. Each call to DEBUG() generates a new header *unless* the
+ * previous debug output was unterminated (i.e. no '\n').
+ * See debug.c:dbghdr() for more info.
+ *
+ * Example: DEBUG( DBGC_TDB, 2, ("Some text and a valu %d.\n", value) );
+ *
+ * DEBUGADD(), DEBUGADDC()
+ * Same as DEBUG() and DEBUGC() except the text is appended to the previous
+ * DEBUG(), DEBUGC(), DEBUGADD(), DEBUGADDC() with out another interviening
+ * header.
+ *
+ * Example: DEBUGADD( 2, ("Some text and a valu %d.\n", value) );
+ * DEBUGADDC( DBGC_TDB, 2, ("Some text and a valu %d.\n", value) );
+ *
+ * Note: If the debug class has not be redeined (see above) then the optimizer
+ * will remove the extra conditional test.
*/
+
#define DEBUGLVL( level ) \
- ( (DEBUGLEVEL >= (level)) \
+ ( ((DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))|| \
+ (DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
+ && dbghdr( level, FILE_MACRO, FUNCTION_MACRO, (__LINE__) ) )
+
+
+#define DEBUGLVLC( dbgc_class, level ) \
+ ( ((DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))|| \
+ (DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
&& dbghdr( level, FILE_MACRO, FUNCTION_MACRO, (__LINE__) ) )
+
#define DEBUG( level, body ) \
- (void)( (DEBUGLEVEL >= (level)) \
+ (void)( ((DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))|| \
+ (DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
+ && (dbghdr( level, FILE_MACRO, FUNCTION_MACRO, (__LINE__) )) \
+ && (dbgtext body) )
+
+#define DEBUGC( dbgc_class, level, body ) \
+ (void)( ((DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))|| \
+ (DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
&& (dbghdr( level, FILE_MACRO, FUNCTION_MACRO, (__LINE__) )) \
&& (dbgtext body) )
#define DEBUGADD( level, body ) \
- (void)( (DEBUGLEVEL >= (level)) && (dbgtext body) )
+ (void)( ((DEBUGLEVEL_CLASS[ DBGC_CLASS ] >= (level))|| \
+ (DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
+ && (dbgtext body) )
-/* End Debugging code section.
- * -------------------------------------------------------------------------- **
- */
+#define DEBUGADDC( dbgc_class, level, body ) \
+ (void)( ((DEBUGLEVEL_CLASS[ dbgc_class ] >= (level))|| \
+ (DEBUGLEVEL_CLASS[ DBGC_ALL ] >= (level)) ) \
+ && (dbgtext body) )
#endif
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 8196c01569..9e0ab60c24 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -49,6 +49,10 @@ uint32 crc32_calc_buffer( char *buffer, uint32 count);
/*The following definitions come from lib/debug.c */
+char* debug_classname_from_index(int idx);
+int debug_lookup_classname(char* classname);
+BOOL debug_parse_params(char **params, int *debuglevel_class);
+BOOL debug_parse_levels(char *params_str);
void debug_message(int msg_type, pid_t src, void *buf, size_t len);
void debug_message_send(pid_t pid, int level);
void setup_logging(char *pname, BOOL interactive);
@@ -179,7 +183,7 @@ void init_msrpc_use(void);
void free_msrpc_use(void);
struct msrpc_state *msrpc_use_add(const char* pipe_name,
uint32 pid,
- const struct user_creds *usr_creds,
+ struct user_creds *usr_creds,
BOOL redir);
BOOL msrpc_use_del(const char* pipe_name,
const struct user_creds *usr_creds,
@@ -1589,6 +1593,7 @@ int lp_maxprotocol(void);
int lp_security(void);
int lp_maxdisksize(void);
int lp_lpqcachetime(void);
+int lp_max_smbd_processes(void);
int lp_totalprintjobs(void);
int lp_syslog(void);
int lp_client_code_page(void);
diff --git a/source3/lib/debug.c b/source3/lib/debug.c
index 9d520b6c2f..e7772bbd38 100644
--- a/source3/lib/debug.c
+++ b/source3/lib/debug.c
@@ -82,7 +82,8 @@
FILE *dbf = NULL;
pstring debugf = "";
BOOL append_log = False;
-int DEBUGLEVEL = 1;
+int DEBUGLEVEL_CLASS[DBGC_LAST];
+int DEBUGLEVEL = DEBUGLEVEL_CLASS;
/* -------------------------------------------------------------------------- **
@@ -114,22 +115,137 @@ static int syslog_level = 0;
static pstring format_bufr = { '\0' };
static size_t format_pos = 0;
+/*
+* Define all the debug class selection names here. Names *MUST NOT* contain
+* white space. There must be one name for each DBGC_<class name>, and they
+* must be in the table in the order of DBGC_<class name>..
+*/
+char *classname_table[] = {
+ "all", /* DBGC_ALL; index references traditional DEBUGLEVEL */
+ "tdb", /* DBGC_TDB */
+ "printdrivers", /* DBGC_PRINTDRIVERS */
+ "lanman", /* DBGC_LANMAN */
+};
+
/* -------------------------------------------------------------------------- **
* Functions...
*/
/****************************************************************************
+utility access to debug class names's
+****************************************************************************/
+char* debug_classname_from_index(int idx)
+{
+ return classname_table[idx];
+}
+
+/****************************************************************************
+utility to translate names to debug class index's
+****************************************************************************/
+int debug_lookup_classname(char* classname)
+{
+ int i;
+
+ if (!classname) return -1;
+
+ for (i=0; i<DBGC_LAST; i++) {
+ if (strcmp(classname, classname_table[i])==0)
+ return i;
+ }
+ return -1;
+}
+
+/****************************************************************************
+parse the debug levels from smbcontrol. Example debug level parameter:
+ printdrivers:7
+****************************************************************************/
+BOOL debug_parse_params(char **params, int *debuglevel_class)
+{
+ int i, idx;
+ char *class_name;
+ char *class_level;
+
+ /* Set the new debug level array to the current DEBUGLEVEL array */
+ memcpy(debuglevel_class, DEBUGLEVEL_CLASS, sizeof(DEBUGLEVEL_CLASS));
+
+ /* Allow DBGC_ALL to be specifies w/o requiring its class name e.g."10"
+ * v.s. "all:10", this is the traditional way to set DEBUGLEVEL
+ */
+ if (isdigit(params[0][0])) {
+ debuglevel_class[DBGC_ALL] = atoi(params[0]);
+ i = 1; /* start processing at the next params */
+ }
+ else
+ i = 0; /* DBGC_ALL not specified OR calss name was included */
+
+ /* Fill in new debug class levels */
+ for (; i < DBGC_LAST && params[i]; i++) {
+ if ((class_name=strtok(params[i],":")) &&
+ (class_level=strtok(NULL, "\0")) &&
+ ((idx = debug_lookup_classname(class_name)) != -1)) {
+ debuglevel_class[idx] = atoi(class_level);
+ } else {
+ DEBUG(0,("debug_parse_params: unrecognized debug class name or format [%s]\n", params[i]));
+ return False;
+ }
+ }
+
+ return True;
+}
+
+/****************************************************************************
+parse the debug levels from smb.conf. Example debug level string:
+ 3 tdb:5 printdrivers:7
+Note: the 1st param has no "name:" preceeding it.
+****************************************************************************/
+BOOL debug_parse_levels(char *params_str)
+{
+ int i;
+ char *params[DBGC_LAST];
+ int debuglevel_class[DBGC_LAST];
+
+ ZERO_ARRAY(params);
+ ZERO_ARRAY(debuglevel_class);
+
+ if ( (params[0]=strtok(params_str," ,")) ) {
+ for (i=1; i<DBGC_LAST;i++) {
+ if ((params[i]=strtok(NULL," ,"))==NULL)
+ break;
+ }
+ }
+ else
+ return False;
+
+ if (debug_parse_params(params, debuglevel_class)) {
+ debug_message(0, getpid(), (void*)debuglevel_class, sizeof(debuglevel_class));
+ return True;
+ } else
+ return False;
+}
+
+/****************************************************************************
receive a "set debug level" message
****************************************************************************/
void debug_message(int msg_type, pid_t src, void *buf, size_t len)
{
- int level;
- memcpy(&level, buf, sizeof(int));
- DEBUGLEVEL = level;
- DEBUG(1,("INFO: Debug level set to %d from pid %d\n", level, (int)src));
+ int i;
+
+ /* Set the new DEBUGLEVEL_CLASS array from the pased array */
+ memcpy(DEBUGLEVEL_CLASS, buf, sizeof(DEBUGLEVEL_CLASS));
+
+ DEBUG(1,("INFO: Debug class %s level = %d (pid %d from pid %d)\n",
+ classname_table[DBGC_ALL],
+ DEBUGLEVEL_CLASS[DBGC_ALL], getpid(), (int)src));
+
+ for (i=1; i<DBGC_LAST; i++) {
+ if (DEBUGLEVEL_CLASS[i])
+ DEBUGADD(1,("INFO: Debug class %s level = %d\n",
+ classname_table[i], DEBUGLEVEL_CLASS[i]));
+ }
}
+
/****************************************************************************
send a "set debug level" message
****************************************************************************/
@@ -175,7 +291,7 @@ void reopen_logs( void )
pstring fname;
mode_t oldumask;
- if (DEBUGLEVEL <= 0) {
+ if (DEBUGLEVEL_CLASS[ DBGC_ALL ] <= 0) {
if (dbf) {
(void)fclose(dbf);
dbf = NULL;
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index 6f6d99c8ec..19496bd426 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -73,7 +73,6 @@ void ping_message(int msg_type, pid_t src, void *buf, size_t len)
DEBUG(1,("INFO: Received PING message from PID %d\n",src));
message_send_pid(src, MSG_PONG, buf, len, True);
}
-
/****************************************************************************
return current debug level
****************************************************************************/
@@ -83,7 +82,7 @@ void debuglevel_message(int msg_type, pid_t src, void *buf, size_t len)
DEBUG(1,("INFO: Received REQ_DEBUGLEVEL message from PID %d\n",src));
level = DEBUGLEVEL;
- message_send_pid(src, MSG_DEBUGLEVEL, &level, sizeof(int), True);
+ message_send_pid(src, MSG_DEBUGLEVEL, DEBUGLEVEL_CLASS, sizeof(DEBUGLEVEL_CLASS), True);
}
/****************************************************************************
diff --git a/source3/lib/msrpc_use.c b/source3/lib/msrpc_use.c
index 7558a266b3..90fac637b3 100644
--- a/source3/lib/msrpc_use.c
+++ b/source3/lib/msrpc_use.c
@@ -109,7 +109,7 @@ find client state. server name, user name, domain name and password must all
match.
****************************************************************************/
static struct msrpc_use *msrpc_find(const char* pipe_name,
- const struct user_creds *usr_creds)
+ struct user_creds *usr_creds)
{
int i;
struct user_creds null_usr;
@@ -199,7 +199,7 @@ init client state
****************************************************************************/
struct msrpc_state *msrpc_use_add(const char* pipe_name,
uint32 pid,
- const struct user_creds *usr_creds,
+ struct user_creds *usr_creds,
BOOL redir)
{
struct msrpc_use *cli;
diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c
index 7130cf0f49..b4cf4930cd 100644
--- a/source3/param/loadparm.c
+++ b/source3/param/loadparm.c
@@ -68,7 +68,7 @@
BOOL in_client = False; /* Not in the client by default */
BOOL bLoaded = False;
-extern int DEBUGLEVEL;
+extern int DEBUGLEVEL_CLASS[DBGC_LAST];
extern pstring user_socket_options;
extern pstring global_myname;
pstring global_scope = "";
@@ -189,6 +189,7 @@ typedef struct
int security;
int maxdisksize;
int lpqcachetime;
+ int iMaxSmbdProcesses;
int iTotalPrintJobs;
int syslog;
int os_level;
@@ -528,6 +529,7 @@ static BOOL handle_source_env(char *pszParmValue, char **ptr);
static BOOL handle_netbios_name(char *pszParmValue, char **ptr);
static BOOL handle_winbind_id(char *pszParmValue, char **ptr);
static BOOL handle_wins_server_list(char *pszParmValue, char **ptr);
+static BOOL handle_debug_list( char *pszParmValue, char **ptr );
static void set_server_role(void);
static void set_default_server_announce_type(void);
@@ -750,8 +752,8 @@ static struct parm_struct parm_table[] = {
#endif /* WITH_SSL */
{"Logging Options", P_SEP, P_SEPARATOR},
- {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, FLAG_BASIC},
- {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL, NULL, NULL, 0},
+ {"log level", P_INTEGER, P_GLOBAL, &DEBUGLEVEL_CLASS[DBGC_ALL], handle_debug_list, NULL, 0},
+ {"debuglevel", P_INTEGER, P_GLOBAL, &DEBUGLEVEL_CLASS[DBGC_ALL], handle_debug_list, NULL, 0},
{"syslog", P_INTEGER, P_GLOBAL, &Globals.syslog, NULL, NULL, 0},
{"syslog only", P_BOOL, P_GLOBAL, &Globals.bSyslogOnly, NULL, NULL, 0},
{"log file", P_STRING, P_GLOBAL, &Globals.szLogFile, NULL, NULL, 0},
@@ -796,6 +798,7 @@ static struct parm_struct parm_table[] = {
{"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0},
{"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0},
+ {"max smbd processes", P_INTEGER, P_GLOBAL, &Globals.iMaxSmbdProcesses, NULL, NULL, 0},
{"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, FLAG_SHARE},
{"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0},
{"max open files", P_INTEGER, P_GLOBAL, &Globals.max_open_files, NULL, NULL, 0},
@@ -1195,6 +1198,7 @@ static void init_globals(void)
Globals.max_xmit = 65535;
Globals.max_mux = 50; /* This is *needed* for profile support. */
Globals.lpqcachetime = 10;
+ Globals.iMaxSmbdProcesses = 0;/* no limit specified */
Globals.iTotalPrintJobs = 0; /* no limit specified */
Globals.pwordlevel = 0;
Globals.unamelevel = 0;
@@ -1520,6 +1524,7 @@ FN_GLOBAL_INTEGER(lp_maxprotocol, &Globals.maxprotocol)
FN_GLOBAL_INTEGER(lp_security, &Globals.security)
FN_GLOBAL_INTEGER(lp_maxdisksize, &Globals.maxdisksize)
FN_GLOBAL_INTEGER(lp_lpqcachetime, &Globals.lpqcachetime)
+FN_GLOBAL_INTEGER(lp_max_smbd_processes, &Globals.iMaxSmbdProcesses)
FN_GLOBAL_INTEGER(lp_totalprintjobs, &Globals.iTotalPrintJobs)
FN_GLOBAL_INTEGER(lp_syslog, &Globals.syslog)
FN_GLOBAL_INTEGER(lp_client_code_page, &Globals.client_code_page)
@@ -2443,6 +2448,18 @@ static BOOL handle_wins_server_list( char *pszParmValue, char **ptr )
/***************************************************************************
+ Handle the DEBUG level list
+***************************************************************************/
+static BOOL handle_debug_list( char *pszParmValueIn, char **ptr )
+{
+ pstring pszParmValue;
+
+ pstrcpy(pszParmValue, pszParmValueIn);
+ return debug_parse_levels( pszParmValue );
+}
+
+
+/***************************************************************************
initialise a copymap
***************************************************************************/
static void init_copymap(service * pservice)
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index ff24849f0b..83c3206a7d 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -3163,22 +3163,33 @@ uint32 printer_write_default_dev(int snum, const PRINTER_DEFAULT *printer_defaul
/*
* Just ignore it if we already have a devmode.
*/
-
+#if 0
if (printer->info_2->devmode != NULL)
goto done;
-
+#endif
/*
* We don't have a devicemode and we're trying to write
* one. Check we have the access needed.
*/
+ DEBUG(5,("printer_write_default_dev: access: %x\n", printer_default->access_required));
+
+ if ( (printer_default->access_required & PRINTER_ACCESS_ADMINISTER) !=
+ PRINTER_ACCESS_ADMINISTER) {
+ DEBUG(5,("printer_write_default_dev: invalid request access to update: %x\n", printer_default->access_required));
+ result = ERROR_ACCESS_DENIED;
+ goto done;
+ }
if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
DEBUG(5,("printer_write_default_dev: Access denied for printer %s\n",
lp_servicename(snum) ));
result = ERROR_ACCESS_DENIED;
+ /*result = NT_STATUS_NO_PROBLEMO;*/
goto done;
}
+ DEBUG(5,("printer_write_default_dev: updating, check OK.\n"));
+
/*
* Convert the on the wire devicemode format to the internal one.
*/
diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c
index 868d90ae74..0961cda195 100644
--- a/source3/rpc_parse/parse_spoolss.c
+++ b/source3/rpc_parse/parse_spoolss.c
@@ -4361,17 +4361,20 @@ BOOL spool_io_printer_driver_info_level_6(char *desc, SPOOL_PRINTER_DRIVER_INFO_
if(!prs_uint32("version", ps, depth, &il->version))
return False;
- if (il->version != 0) {
- /*
- * If version != 0 then there are an extra 4 bytes.
- * JohnR and I have verified this at Roseville... JRA.
- */
- if(!prs_uint32("dummy4", ps, depth, &il->dummy4))
- return False;
- }
if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
- return False;
+ return False;
+ /*
+ * If name_ptr is NULL then the next 4 bytes are the name_ptr. A driver
+ * with a NULL name just isn't a driver For example: "HP LaserJet 4si"
+ * from W2K CDROM (which uses unidriver). JohnR 010205
+ */
+ if (!il->name_ptr) {
+ DEBUG(5,("spool_io_printer_driver_info_level_6: name_ptr is NULL! Get next value\n"));
+ if(!prs_uint32("name_ptr", ps, depth, &il->name_ptr))
+ return False;
+ }
+
if(!prs_uint32("environment_ptr", ps, depth, &il->environment_ptr))
return False;
if(!prs_uint32("driverpath_ptr", ps, depth, &il->driverpath_ptr))
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 19f5859abb..207786768b 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -291,7 +291,7 @@ static void get_filename_transact( char *fname, char *inbuf, int data_offset, in
* the end here.
*/
- if((data_len - fname_len == 1) || (inbuf[data_offset] == '\0')) {
+ if((data_len == 1) || (inbuf[data_offset] == '\0')) {
/*
* Ensure that the data offset is aligned
* on a 2 byte boundary - add one if not.
@@ -1110,6 +1110,15 @@ static BOOL set_sd(files_struct *fsp, char *data, uint32 sd_len, uint security_i
return False;
}
+ if (psd->off_owner_sid==0)
+ security_info_sent &= ~OWNER_SECURITY_INFORMATION;
+ if (psd->off_grp_sid==0)
+ security_info_sent &= ~GROUP_SECURITY_INFORMATION;
+ if (psd->off_sacl==0)
+ security_info_sent &= ~DACL_SECURITY_INFORMATION;
+ if (psd->off_dacl==0)
+ security_info_sent &= ~SACL_SECURITY_INFORMATION;
+
ret = set_nt_acl( fsp, security_info_sent, psd);
if (!ret) {
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index ed8c0a94c9..db2f933420 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -238,6 +238,8 @@ static BOOL unpack_nt_owners(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *pgrp,
DEBUG(3,("unpack_nt_owners: unable to validate group sid.\n"));
}
+ DEBUG(5,("unpack_nt_owners: owner_sids validated.\n"));
+
return True;
}
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index eb18219992..461fa99f39 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -769,6 +769,30 @@ static int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
return(outsize);
}
+/****************************************************************************
+ Keep track of the number of running smbd's. This functionality is used to
+ 'hard' limit Samba overhead on resource constrained systems.
+****************************************************************************/
+static BOOL smbd_process_limit(void)
+{
+ int total_smbds;
+
+ if (lp_max_smbd_processes()) {
+
+ /* Always add one to the smbd process count, as exit_server() always
+ * subtracts one.
+ */
+ tdb_lock_bystring(conn_tdb_ctx(), "INFO/total_smbds");
+ total_smbds = tdb_fetch_int(conn_tdb_ctx(), "INFO/total_smbds");
+ total_smbds = total_smbds < 0 ? 1 : total_smbds + 1;
+ tdb_store_int(conn_tdb_ctx(), "INFO/total_smbds", total_smbds);
+ tdb_unlock_bystring(conn_tdb_ctx(), "INFO/total_smbds");
+
+ return total_smbds > lp_max_smbd_processes();
+ }
+ else
+ return False;
+}
/****************************************************************************
process an smb from the client - split out from the process() code so
@@ -792,8 +816,9 @@ void process_smb(char *inbuf, char *outbuf)
deny parameters before doing any parsing of the packet
passed to us by the client. This prevents attacks on our
parsing code from hosts not in the hosts allow list */
- if (!check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1))) {
- /* send a negative session response "not listining on calling
+ if (smbd_process_limit() ||
+ !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1))) {
+ /* send a negative session response "not listening on calling
name" */
static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
DEBUG( 1, ( "Connection denied from %s\n",
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index b24ec7a944..2d205543fb 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -510,9 +510,9 @@ int smb_create_user(char *unix_user, char *homedir)
pstrcpy(add_script, lp_adduser_script());
if (! *add_script) return -1;
- pstring_sub(add_script, "%u", unix_user);
+ all_string_sub(add_script, "%u", unix_user, sizeof(pstring));
if (homedir)
- pstring_sub(add_script, "%H", homedir);
+ all_string_sub(add_script, "%H", homedir, sizeof(pstring));
ret = smbrun(add_script,NULL,False);
DEBUG(3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
return ret;
@@ -529,7 +529,7 @@ static int smb_delete_user(char *unix_user)
pstrcpy(del_script, lp_deluser_script());
if (! *del_script) return -1;
- pstring_sub(del_script, "%u", unix_user);
+ all_string_sub(del_script, "%u", unix_user, sizeof(pstring));
ret = smbrun(del_script,NULL,False);
DEBUG(3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
return ret;
@@ -898,10 +898,10 @@ int reply_sesssetup_and_X(connection_struct *conn, char *inbuf,char *outbuf,int
/* if the username exists as a domain/username pair on the unix system then use
that */
- if (!getpwnam(user)) {
+ if (!sys_getpwnam(user)) {
pstring user2;
slprintf(user2,sizeof(user2),"%s%s%s", dos_to_unix(domain,False), lp_winbind_separator(), user);
- if (getpwnam(user2)) {
+ if (sys_getpwnam(user2)) {
DEBUG(3,("Using unix username %s\n", user2));
pstrcpy(user, user2);
}
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index a13f34d506..8eacd4ed58 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -410,6 +410,22 @@ static BOOL dump_core(void)
#endif
/****************************************************************************
+update the current smbd process count
+****************************************************************************/
+static void decrement_smbd_process_count(void)
+{
+ int total_smbds;
+
+ if (lp_max_smbd_processes()) {
+ tdb_lock_bystring(conn_tdb_ctx(), "INFO/total_smbds");
+ if ((total_smbds = tdb_fetch_int(conn_tdb_ctx(), "INFO/total_smbds")) > 0)
+ tdb_store_int(conn_tdb_ctx(), "INFO/total_smbds", total_smbds - 1);
+
+ tdb_unlock_bystring(conn_tdb_ctx(), "INFO/total_smbds");
+ }
+}
+
+/****************************************************************************
exit the server
****************************************************************************/
void exit_server(char *reason)
@@ -432,6 +448,7 @@ void exit_server(char *reason)
}
respond_to_all_remaining_local_messages();
+ decrement_smbd_process_count();
#ifdef WITH_DFS
if (dcelogin_atmost_once) {
diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c
index 87d00eecbd..26c01ced9e 100644
--- a/source3/utils/smbcontrol.c
+++ b/source3/utils/smbcontrol.c
@@ -77,10 +77,17 @@ Prints out the current Debug level returned by MSG_DEBUGLEVEL
****************************************************************************/
void debuglevel_function(int msg_type, pid_t src, void *buf, size_t len)
{
- int level;
- memcpy(&level, buf, sizeof(int));
+ int i;
+ int debuglevel_class[DBGC_LAST];
+
+ memcpy(debuglevel_class, buf, len);
+
+ printf("Current debug level of PID %d is %d ",src, debuglevel_class[0]);
+ for (i=1;i<DBGC_LAST;i++)
+ if (debuglevel_class[i])
+ printf("%s:%d ", debug_classname_from_index(i), debuglevel_class[i]);
+ printf("\n");
- printf("Current debug level of PID %d is %d\n",src,level);
got_level = True;
}
@@ -164,11 +171,12 @@ static int parse_type(char *mtype)
/****************************************************************************
do command
****************************************************************************/
-static BOOL do_command(char *dest, char *msg_name, char *params)
+static BOOL do_command(char *dest, char *msg_name, char *params[])
{
int i, n, v;
int mtype;
BOOL retval;
+ int debuglevel_class[DBGC_LAST];
mtype = parse_type(msg_name);
if (mtype == -1) {
@@ -178,26 +186,31 @@ static BOOL do_command(char *dest, char *msg_name, char *params)
switch (mtype) {
case MSG_DEBUG:
- if (!params) {
+ if (!params[0]) {
fprintf(stderr,"MSG_DEBUG needs a parameter\n");
return(False);
}
- v = atoi(params);
- send_message(dest, MSG_DEBUG, &v, sizeof(int), False);
+
+ ZERO_ARRAY(debuglevel_class);
+ if (!debug_parse_params(params, debuglevel_class)) {
+ fprintf(stderr, "MSG_DEBUG error. Expected <class name>:level\n");
+ return(False);
+ } else
+ send_message(dest, MSG_DEBUG, debuglevel_class, sizeof(debuglevel_class), False);
break;
case MSG_PROFILE:
- if (!params) {
+ if (!params[0]) {
fprintf(stderr,"MSG_PROFILE needs a parameter\n");
return(False);
}
- if (strequal(params, "off")) {
+ if (strequal(params[0], "off")) {
v = 0;
- } else if (strequal(params, "count")) {
+ } else if (strequal(params[0], "count")) {
v = 1;
- } else if (strequal(params, "on")) {
+ } else if (strequal(params[0], "on")) {
v = 2;
- } else if (strequal(params, "flush")) {
+ } else if (strequal(params[0], "flush")) {
v = 3;
} else {
fprintf(stderr,
@@ -258,12 +271,12 @@ static BOOL do_command(char *dest, char *msg_name, char *params)
fprintf(stderr,"printer-notify can only be sent to smbd\n");
return(False);
}
- if (!params) {
+ if (!params[0]) {
fprintf(stderr, "printer-notify needs a printer name\n");
return (False);
}
- retval = send_message(dest, MSG_PRINTER_NOTIFY, params,
- strlen(params) + 1, False);
+ retval = send_message(dest, MSG_PRINTER_NOTIFY, params[0],
+ strlen(params[0]) + 1, False);
break;
case MSG_PING:
@@ -271,11 +284,11 @@ static BOOL do_command(char *dest, char *msg_name, char *params)
message_register(MSG_PONG, pong_function);
pong_registered = True;
}
- if (!params) {
+ if (!params[0]) {
fprintf(stderr,"MSG_PING needs a parameter\n");
return(False);
}
- n = atoi(params);
+ n = atoi(params[0]);
pong_count = 0;
for (i=0;i<n;i++) {
retval = send_message(dest, MSG_PING, NULL, 0, True);
@@ -332,7 +345,7 @@ static BOOL do_command(char *dest, char *msg_name, char *params)
if (!interactive) {
if (argc < 2) usage(True);
- return (do_command(argv[0],argv[1],argc > 2 ? argv[2] : 0));
+ return (do_command(argv[0],argv[1],argc > 2 ? &argv[2] : 0));
}
while (True) {
@@ -350,7 +363,7 @@ static BOOL do_command(char *dest, char *msg_name, char *params)
if (strequal(myargv[0],"q")) break;
if (myargc < 2)
usage(False);
- else if (!do_command(myargv[0],myargv[1],myargc > 2 ? myargv[2] : 0))
+ else if (!do_command(myargv[0],myargv[1],myargc > 2 ? &myargv[2] : 0))
usage(False);
}
return(0);