diff options
-rw-r--r-- | source3/include/debug.h | 132 | ||||
-rw-r--r-- | source3/include/proto.h | 7 | ||||
-rw-r--r-- | source3/lib/debug.c | 128 | ||||
-rw-r--r-- | source3/lib/messages.c | 3 | ||||
-rw-r--r-- | source3/lib/msrpc_use.c | 4 | ||||
-rw-r--r-- | source3/param/loadparm.c | 23 | ||||
-rw-r--r-- | source3/printing/nt_printing.c | 15 | ||||
-rw-r--r-- | source3/rpc_parse/parse_spoolss.c | 21 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 11 | ||||
-rw-r--r-- | source3/smbd/posix_acls.c | 2 | ||||
-rw-r--r-- | source3/smbd/process.c | 29 | ||||
-rw-r--r-- | source3/smbd/reply.c | 10 | ||||
-rw-r--r-- | source3/smbd/server.c | 17 | ||||
-rw-r--r-- | source3/utils/smbcontrol.c | 51 |
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); |