summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-09-30 17:13:37 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:04:48 -0500
commit54abd2aa66069e6baf7769c496f46d9dba18db39 (patch)
tree9cf8e88168011797319ba9e9866749201b1eac1e /source3/lib
parent4a2cc231d22a82ed21771a72508f15d21ed63227 (diff)
downloadsamba-54abd2aa66069e6baf7769c496f46d9dba18db39.tar.gz
samba-54abd2aa66069e6baf7769c496f46d9dba18db39.tar.bz2
samba-54abd2aa66069e6baf7769c496f46d9dba18db39.zip
r10656: BIG merge from trunk. Features not copied over
* \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3)
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/account_pol.c372
-rw-r--r--source3/lib/arc4.c80
-rw-r--r--source3/lib/data_blob.c20
-rw-r--r--source3/lib/debug.c18
-rw-r--r--source3/lib/dmallocmsg.c4
-rw-r--r--source3/lib/gencache.c16
-rw-r--r--source3/lib/genrand.c61
-rw-r--r--source3/lib/messages.c57
-rw-r--r--source3/lib/module.c74
-rw-r--r--source3/lib/pidfile.c2
-rw-r--r--source3/lib/privileges.c5
-rw-r--r--source3/lib/smbldap.c6
-rw-r--r--source3/lib/smbldap_util.c66
-rw-r--r--source3/lib/smbrun.c8
-rw-r--r--source3/lib/tallocmsg.c4
-rw-r--r--source3/lib/time.c138
-rw-r--r--source3/lib/util.c70
17 files changed, 720 insertions, 281 deletions
diff --git a/source3/lib/account_pol.c b/source3/lib/account_pol.c
index 423dc1675a..b02edc5b40 100644
--- a/source3/lib/account_pol.c
+++ b/source3/lib/account_pol.c
@@ -3,6 +3,7 @@
* account policy storage
* Copyright (C) Jean François Micouleau 1998-2001.
* Copyright (C) Andrew Bartlett 2002
+ * Copyright (C) Guenther Deschner 2004-2005
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -22,102 +23,65 @@
#include "includes.h"
static TDB_CONTEXT *tdb;
-#define DATABASE_VERSION 2
+/* cache all entries for 60 seconds for to save ldap-queries (cache is updated
+ * after this period if admins do not use pdbedit or usermanager but manipulate
+ * ldap directly) - gd */
-/****************************************************************************
- Set default for a field if it is empty
-****************************************************************************/
-
-static void set_default_on_empty(int field, uint32 value)
-{
- if (account_policy_get(field, NULL))
- return;
- account_policy_set(field, value);
- return;
-}
+#define DATABASE_VERSION 3
+#define AP_LASTSET "LAST_CACHE_UPDATE"
+#define AP_TTL 60
-/****************************************************************************
- Open the account policy tdb.
-****************************************************************************/
-BOOL init_account_policy(void)
-{
- const char *vstring = "INFO/version";
- uint32 version;
+struct ap_table {
+ int field;
+ const char *string;
+ uint32 default_val;
+ const char *description;
+ const char *ldap_attr;
+};
- if (tdb)
- return True;
- tdb = tdb_open_log(lock_path("account_policy.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
- if (!tdb) {
- DEBUG(0,("Failed to open account policy database\n"));
- return False;
- }
+static const struct ap_table account_policy_names[] = {
+ {AP_MIN_PASSWORD_LEN, "min password length", MINPASSWDLENGTH,
+ "Minimal password length (default: 5)",
+ "sambaMinPwdLength" },
- /* handle a Samba upgrade */
- tdb_lock_bystring(tdb, vstring,0);
- if (!tdb_fetch_uint32(tdb, vstring, &version) || version != DATABASE_VERSION) {
- tdb_store_uint32(tdb, vstring, DATABASE_VERSION);
+ {AP_PASSWORD_HISTORY, "password history", 0,
+ "Length of Password History Entries (default: 0 => off)",
+ "sambaPwdHistoryLength" },
- set_default_on_empty(
- AP_MIN_PASSWORD_LEN,
- MINPASSWDLENGTH);/* 5 chars minimum */
- set_default_on_empty(
- AP_PASSWORD_HISTORY,
- 0); /* don't keep any old password */
- set_default_on_empty(
- AP_USER_MUST_LOGON_TO_CHG_PASS,
- 0); /* don't force user to logon */
- set_default_on_empty(
- AP_MAX_PASSWORD_AGE,
- (uint32)-1); /* don't expire */
- set_default_on_empty(
- AP_MIN_PASSWORD_AGE,
- 0); /* 0 days */
- set_default_on_empty(
- AP_LOCK_ACCOUNT_DURATION,
- 30); /* lockout for 30 minutes */
- set_default_on_empty(
- AP_RESET_COUNT_TIME,
- 30); /* reset after 30 minutes */
- set_default_on_empty(
- AP_BAD_ATTEMPT_LOCKOUT,
- 0); /* don't lockout */
- set_default_on_empty(
- AP_TIME_TO_LOGOUT,
- -1); /* don't force logout */
- set_default_on_empty(
- AP_REFUSE_MACHINE_PW_CHANGE,
- 0); /* allow machine pw changes */
- }
- tdb_unlock_bystring(tdb, vstring);
-
- /* These exist by default on NT4 in [HKLM\SECURITY\Policy\Accounts] */
-
- privilege_create_account( &global_sid_World );
- privilege_create_account( &global_sid_Builtin_Administrators );
- privilege_create_account( &global_sid_Builtin_Account_Operators );
- privilege_create_account( &global_sid_Builtin_Server_Operators );
- privilege_create_account( &global_sid_Builtin_Print_Operators );
- privilege_create_account( &global_sid_Builtin_Backup_Operators );
+ {AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password", 0,
+ "Force Users to logon for password change (default: 0 => off, 2 => on)",
+ "sambaLogonToChgPwd" },
- return True;
-}
-
-static const struct {
- int field;
- const char *string;
-} account_policy_names[] = {
- {AP_MIN_PASSWORD_LEN, "min password length"},
- {AP_PASSWORD_HISTORY, "password history"},
- {AP_USER_MUST_LOGON_TO_CHG_PASS, "user must logon to change password"},
- {AP_MAX_PASSWORD_AGE, "maximum password age"},
- {AP_MIN_PASSWORD_AGE,"minimum password age"},
- {AP_LOCK_ACCOUNT_DURATION, "lockout duration"},
- {AP_RESET_COUNT_TIME, "reset count minutes"},
- {AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt"},
- {AP_TIME_TO_LOGOUT, "disconnect time"},
- {AP_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change"},
- {0, NULL}
+ {AP_MAX_PASSWORD_AGE, "maximum password age", (uint32) -1,
+ "Maximum password age, in seconds (default: -1 => never expire passwords)",
+ "sambaMaxPwdAge" },
+
+ {AP_MIN_PASSWORD_AGE,"minimum password age", 0,
+ "Minimal password age, in seconds (default: 0 => allow immediate password change)",
+ "sambaMinPwdAge" },
+
+ {AP_LOCK_ACCOUNT_DURATION, "lockout duration", 30,
+ "Lockout duration in minutes (default: 30, -1 => forever)",
+ "sambaLockoutDuration" },
+
+ {AP_RESET_COUNT_TIME, "reset count minutes", 30,
+ "Reset time after lockout in minutes (default: 30)",
+ "sambaLockoutObservationWindow" },
+
+ {AP_BAD_ATTEMPT_LOCKOUT, "bad lockout attempt", 0,
+ "Lockout users after bad logon attempts (default: 0 => off)",
+ "sambaLockoutThreshold" },
+
+ {AP_TIME_TO_LOGOUT, "disconnect time", -1,
+ "Disconnect Users outside logon hours (default: -1 => off, 0 => on)",
+ "sambaForceLogoff" },
+
+ {AP_REFUSE_MACHINE_PW_CHANGE, "refuse machine password change", 0,
+ "Allow Machine Password changes (default: 0 => off)",
+ "sambaRefuseMachinePwdChange" },
+
+ {0, NULL, 0, "", NULL}
};
char *account_policy_names_list(void)
@@ -148,7 +112,7 @@ char *account_policy_names_list(void)
Get the account policy name as a string from its #define'ed number
****************************************************************************/
-static const char *decode_account_policy_name(int field)
+const char *decode_account_policy_name(int field)
{
int i;
for (i=0; account_policy_names[i].string; i++) {
@@ -156,7 +120,34 @@ static const char *decode_account_policy_name(int field)
return account_policy_names[i].string;
}
return NULL;
+}
+
+/****************************************************************************
+Get the account policy LDAP attribute as a string from its #define'ed number
+****************************************************************************/
+const char *get_account_policy_attr(int field)
+{
+ int i;
+ for (i=0; account_policy_names[i].field; i++) {
+ if (field == account_policy_names[i].field)
+ return account_policy_names[i].ldap_attr;
+ }
+ return NULL;
+}
+
+/****************************************************************************
+Get the account policy description as a string from its #define'ed number
+****************************************************************************/
+
+const char *account_policy_get_desc(int field)
+{
+ int i;
+ for (i=0; account_policy_names[i].string; i++) {
+ if (field == account_policy_names[i].field)
+ return account_policy_names[i].description;
+ }
+ return NULL;
}
/****************************************************************************
@@ -171,18 +162,146 @@ int account_policy_name_to_fieldnum(const char *name)
return account_policy_names[i].field;
}
return 0;
+}
+
+/*****************************************************************************
+Update LAST-Set counter inside the cache
+*****************************************************************************/
+
+static BOOL account_policy_cache_timestamp(uint32 *value, BOOL update,
+ const char *ap_name)
+{
+ pstring key;
+ uint32 val = 0;
+ time_t now;
+
+ if (ap_name == NULL)
+ return False;
+
+ slprintf(key, sizeof(key)-1, "%s/%s", ap_name, AP_LASTSET);
+
+ if (!init_account_policy())
+ return False;
+
+ if (!tdb_fetch_uint32(tdb, key, &val) && !update) {
+ DEBUG(10,("failed to get last set timestamp of cache\n"));
+ return False;
+ }
+
+ *value = val;
+
+ DEBUG(10, ("account policy cache lastset was: %s\n", http_timestring(val)));
+
+ if (update) {
+
+ now = time(NULL);
+ if (!tdb_store_uint32(tdb, key, (uint32)now)) {
+ DEBUG(1, ("tdb_store_uint32 failed for %s\n", key));
+ return False;
+ }
+ DEBUG(10, ("account policy cache lastset now: %s\n", http_timestring(now)));
+ *value = now;
+ }
+
+ return True;
}
-/****************************************************************************
-****************************************************************************/
+/*****************************************************************************
+Get default value for account policy
+*****************************************************************************/
+
+BOOL account_policy_get_default(int account_policy, uint32 *val)
+{
+ int i;
+ for (i=0; account_policy_names[i].field; i++) {
+ if (account_policy_names[i].field == account_policy) {
+ *val = account_policy_names[i].default_val;
+ return True;
+ }
+ }
+ DEBUG(0,("no default for account_policy index %d found. This should never happen\n",
+ account_policy));
+ return False;
+}
+
+/*****************************************************************************
+ Set default for a field if it is empty
+*****************************************************************************/
+
+static BOOL account_policy_set_default_on_empty(int account_policy)
+{
+
+ uint32 value;
+
+ if (!account_policy_get(account_policy, &value) &&
+ !account_policy_get_default(account_policy, &value)) {
+ return False;
+ }
+
+ return account_policy_set(account_policy, value);
+}
+
+/*****************************************************************************
+ Open the account policy tdb.
+***`*************************************************************************/
+
+BOOL init_account_policy(void)
+{
+
+ const char *vstring = "INFO/version";
+ uint32 version;
+ int i;
+
+ if (tdb)
+ return True;
+
+ tdb = tdb_open_log(lock_path("account_policy.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ if (!tdb) {
+ DEBUG(0,("Failed to open account policy database\n"));
+ return False;
+ }
+
+ /* handle a Samba upgrade */
+ tdb_lock_bystring(tdb, vstring,0);
+ if (!tdb_fetch_uint32(tdb, vstring, &version) || version != DATABASE_VERSION) {
+
+ tdb_store_uint32(tdb, vstring, DATABASE_VERSION);
+
+ for (i=0; account_policy_names[i].field; i++) {
+
+ if (!account_policy_set_default_on_empty(account_policy_names[i].field)) {
+ DEBUG(0,("failed to set default value in account policy tdb\n"));
+ return False;
+ }
+ }
+ }
+
+ tdb_unlock_bystring(tdb, vstring);
+
+ /* These exist by default on NT4 in [HKLM\SECURITY\Policy\Accounts] */
+
+ privilege_create_account( &global_sid_World );
+ privilege_create_account( &global_sid_Builtin_Administrators );
+ privilege_create_account( &global_sid_Builtin_Account_Operators );
+ privilege_create_account( &global_sid_Builtin_Server_Operators );
+ privilege_create_account( &global_sid_Builtin_Print_Operators );
+ privilege_create_account( &global_sid_Builtin_Backup_Operators );
+
+ return True;
+}
+
+/*****************************************************************************
+Get an account policy (from tdb)
+*****************************************************************************/
BOOL account_policy_get(int field, uint32 *value)
{
fstring name;
uint32 regval;
- if(!init_account_policy())return False;
+ if (!init_account_policy())
+ return False;
if (value)
*value = 0;
@@ -199,18 +318,21 @@ BOOL account_policy_get(int field, uint32 *value)
if (value)
*value = regval;
- DEBUG(10,("account_policy_get: %s:%d\n", name, regval));
+ DEBUG(10,("account_policy_get: name: %s, val: %d\n", name, regval));
return True;
}
/****************************************************************************
+Set an account policy (in tdb)
****************************************************************************/
+
BOOL account_policy_set(int field, uint32 value)
{
fstring name;
- if(!init_account_policy())return False;
+ if (!init_account_policy())
+ return False;
fstrcpy(name, decode_account_policy_name(field));
if (!*name) {
@@ -219,16 +341,72 @@ BOOL account_policy_set(int field, uint32 value)
}
if (!tdb_store_uint32(tdb, name, value)) {
- DEBUG(1, ("tdb_store_uint32 failed for field %d (%s) on value %u", field, name, value));
+ DEBUG(1, ("tdb_store_uint32 failed for field %d (%s) on value %u\n", field, name, value));
return False;
}
- DEBUG(10,("account_policy_set: %s:%d\n", name, value));
+ DEBUG(10,("account_policy_set: name: %s, value: %d\n", name, value));
return True;
}
/****************************************************************************
+Set an account policy in the cache
+****************************************************************************/
+
+BOOL cache_account_policy_set(int field, uint32 value)
+{
+ uint32 lastset;
+ const char *policy_name = NULL;
+
+ policy_name = decode_account_policy_name(field);
+ if (policy_name == NULL) {
+ DEBUG(0,("cache_account_policy_set: no policy found\n"));
+ return False;
+ }
+
+ DEBUG(10,("cache_account_policy_set: updating account pol cache\n"));
+
+ if (!account_policy_set(field, value)) {
+ return False;
+ }
+
+ if (!account_policy_cache_timestamp(&lastset, True, policy_name))
+ {
+ DEBUG(10,("cache_account_policy_set: failed to get lastest cache update timestamp\n"));
+ return False;
+ }
+
+ DEBUG(10,("cache_account_policy_set: cache valid until: %s\n", http_timestring(lastset+AP_TTL)));
+
+ return True;
+}
+
+/*****************************************************************************
+Get an account policy from the cache
+*****************************************************************************/
+
+BOOL cache_account_policy_get(int field, uint32 *value)
+{
+ uint32 lastset;
+
+ if (!account_policy_cache_timestamp(&lastset, False,
+ decode_account_policy_name(field)))
+ {
+ DEBUG(10,("cache_account_policy_get: failed to get latest cache update timestamp\n"));
+ return False;
+ }
+
+ if ((lastset + AP_TTL) < (uint32)time(NULL) ) {
+ DEBUG(10,("cache_account_policy_get: no valid cache entry (cache expired)\n"));
+ return False;
+ }
+
+ return account_policy_get(field, value);
+}
+
+
+/****************************************************************************
****************************************************************************/
TDB_CONTEXT *get_account_pol_tdb( void )
diff --git a/source3/lib/arc4.c b/source3/lib/arc4.c
new file mode 100644
index 0000000000..03ca54c324
--- /dev/null
+++ b/source3/lib/arc4.c
@@ -0,0 +1,80 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ An implementation of arc4.
+
+ Copyright (C) Jeremy Allison 2005.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+/*****************************************************************
+ Initialize state for an arc4 crypt/decrpyt.
+ arc4 state is 258 bytes - last 2 bytes are the index bytes.
+*****************************************************************/
+
+void smb_arc4_init(unsigned char arc4_state_out[258], const unsigned char *key, size_t keylen)
+{
+ size_t ind;
+ unsigned char j = 0;
+
+ for (ind = 0; ind < 256; ind++) {
+ arc4_state_out[ind] = (unsigned char)ind;
+ }
+
+ for( ind = 0; ind < 256; ind++) {
+ unsigned char tc;
+
+ j += (arc4_state_out[ind] + key[ind%keylen]);
+
+ tc = arc4_state_out[ind];
+ arc4_state_out[ind] = arc4_state_out[j];
+ arc4_state_out[j] = tc;
+ }
+ arc4_state_out[256] = 0;
+ arc4_state_out[257] = 0;
+}
+
+/*****************************************************************
+ Do the arc4 crypt/decrpyt.
+ arc4 state is 258 bytes - last 2 bytes are the index bytes.
+*****************************************************************/
+
+void smb_arc4_crypt(unsigned char arc4_state_inout[258], unsigned char *data, size_t len)
+{
+ unsigned char index_i = arc4_state_inout[256];
+ unsigned char index_j = arc4_state_inout[257];
+ size_t ind;
+
+ for( ind = 0; ind < len; ind++) {
+ unsigned char tc;
+ unsigned char t;
+
+ index_i++;
+ index_j += arc4_state_inout[index_i];
+
+ tc = arc4_state_inout[index_i];
+ arc4_state_inout[index_i] = arc4_state_inout[index_j];
+ arc4_state_inout[index_j] = tc;
+
+ t = arc4_state_inout[index_i] + arc4_state_inout[index_j];
+ data[ind] = data[ind] ^ arc4_state_inout[t];
+ }
+
+ arc4_state_inout[256] = index_i;
+ arc4_state_inout[257] = index_j;
+}
diff --git a/source3/lib/data_blob.c b/source3/lib/data_blob.c
index 161f46a941..ccd0d27f47 100644
--- a/source3/lib/data_blob.c
+++ b/source3/lib/data_blob.c
@@ -22,8 +22,9 @@
#include "includes.h"
/*******************************************************************
- free() a data blob
+ Free() a data blob.
*******************************************************************/
+
static void free_data_blob(DATA_BLOB *d)
{
if ((d) && (d->free)) {
@@ -32,8 +33,8 @@ static void free_data_blob(DATA_BLOB *d)
}
/*******************************************************************
- construct a data blob, must be freed with data_blob_free()
- you can pass NULL for p and get a blank data blob
+ Construct a data blob, must be freed with data_blob_free().
+ You can pass NULL for p and get a blank data blob
*******************************************************************/
DATA_BLOB data_blob(const void *p, size_t length)
@@ -56,8 +57,9 @@ DATA_BLOB data_blob(const void *p, size_t length)
}
/*******************************************************************
- construct a data blob, using supplied TALLOC_CTX
+ Construct a data blob, using supplied TALLOC_CTX.
*******************************************************************/
+
DATA_BLOB data_blob_talloc(TALLOC_CTX *mem_ctx, const void *p, size_t length)
{
DATA_BLOB ret;
@@ -83,8 +85,9 @@ DATA_BLOB data_blob_talloc(TALLOC_CTX *mem_ctx, const void *p, size_t length)
}
/*******************************************************************
-free a data blob
+ Free a data blob.
*******************************************************************/
+
void data_blob_free(DATA_BLOB *d)
{
if (d) {
@@ -96,8 +99,9 @@ void data_blob_free(DATA_BLOB *d)
}
/*******************************************************************
-clear a DATA_BLOB's contents
+ Clear a DATA_BLOB's contents
*******************************************************************/
+
static void data_blob_clear(DATA_BLOB *d)
{
if (d->data) {
@@ -106,11 +110,11 @@ static void data_blob_clear(DATA_BLOB *d)
}
/*******************************************************************
-free a data blob and clear its contents
+ Free a data blob and clear its contents
*******************************************************************/
+
void data_blob_clear_free(DATA_BLOB *d)
{
data_blob_clear(d);
data_blob_free(d);
}
-
diff --git a/source3/lib/debug.c b/source3/lib/debug.c
index f877d540fb..f3676070dc 100644
--- a/source3/lib/debug.c
+++ b/source3/lib/debug.c
@@ -448,19 +448,22 @@ BOOL debug_parse_levels(const char *params_str)
Receive a "set debug level" message.
****************************************************************************/
-static void debug_message(int msg_type, pid_t src, void *buf, size_t len)
+static void debug_message(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
const char *params_str = buf;
/* Check, it's a proper string! */
if (params_str[len-1] != '\0') {
DEBUG(1, ("Invalid debug message from pid %u to pid %u\n",
- (unsigned int)src, (unsigned int)getpid()));
+ (unsigned int)procid_to_pid(&src),
+ (unsigned int)getpid()));
return;
}
DEBUG(3, ("INFO: Remote set of debug to `%s' (pid %u from pid %u)\n",
- params_str, (unsigned int)getpid(), (unsigned int)src));
+ params_str, (unsigned int)getpid(),
+ (unsigned int)procid_to_pid(&src)));
debug_parse_levels(params_str);
}
@@ -473,7 +476,8 @@ void debug_message_send(pid_t pid, const char *params_str)
{
if (!params_str)
return;
- message_send_pid(pid, MSG_DEBUG, params_str, strlen(params_str) + 1,
+ message_send_pid(pid_to_procid(pid), MSG_DEBUG,
+ params_str, strlen(params_str) + 1,
False);
}
@@ -481,11 +485,13 @@ void debug_message_send(pid_t pid, const char *params_str)
Return current debug level.
****************************************************************************/
-static void debuglevel_message(int msg_type, pid_t src, void *buf, size_t len)
+static void debuglevel_message(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
char *message = debug_list_class_names_and_levels();
- DEBUG(1,("INFO: Received REQ_DEBUGLEVEL message from PID %u\n",(unsigned int)src));
+ DEBUG(1,("INFO: Received REQ_DEBUGLEVEL message from PID %u\n",
+ (unsigned int)procid_to_pid(&src)));
message_send_pid(src, MSG_DEBUGLEVEL, message, strlen(message) + 1, True);
SAFE_FREE(message);
diff --git a/source3/lib/dmallocmsg.c b/source3/lib/dmallocmsg.c
index a83ed518d7..1b2308ecba 100644
--- a/source3/lib/dmallocmsg.c
+++ b/source3/lib/dmallocmsg.c
@@ -35,7 +35,7 @@ static unsigned long our_dm_mark = 0;
* Respond to a POOL_USAGE message by sending back string form of memory
* usage stats.
**/
-static void msg_req_dmalloc_mark(int UNUSED(msg_type), pid_t UNUSED(src_pid),
+static void msg_req_dmalloc_mark(int UNUSED(msg_type), struct process_id UNUSED(src_pid),
void *UNUSED(buf), size_t UNUSED(len))
{
#ifdef ENABLE_DMALLOC
@@ -49,7 +49,7 @@ static void msg_req_dmalloc_mark(int UNUSED(msg_type), pid_t UNUSED(src_pid),
static void msg_req_dmalloc_log_changed(int UNUSED(msg_type),
- pid_t UNUSED(src_pid),
+ struct process_id UNUSED(src_pid),
void *UNUSED(buf), size_t UNUSED(len))
{
#ifdef ENABLE_DMALLOC
diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
index f2e267c9d4..85599c92d3 100644
--- a/source3/lib/gencache.c
+++ b/source3/lib/gencache.c
@@ -251,11 +251,17 @@ BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout)
char* entry_buf = SMB_STRNDUP(databuf.dptr, databuf.dsize);
char *v;
time_t t;
+ unsigned u;
+ int status;
v = SMB_MALLOC(databuf.dsize - TIMEOUT_LEN);
SAFE_FREE(databuf.dptr);
- sscanf(entry_buf, CACHE_DATA_FMT, (int*)&t, v);
+ status = sscanf(entry_buf, CACHE_DATA_FMT, &u, v);
+ if ( status != 2 ) {
+ DEBUG(0, ("gencache_get: Invalid return %d from sscanf\n", status ));
+ }
+ t = u;
SAFE_FREE(entry_buf);
DEBUG(10, ("Returning %s cache entry: key = %s, value = %s, "
@@ -307,6 +313,8 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time
TDB_DATA databuf;
char *keystr = NULL, *valstr = NULL, *entry = NULL;
time_t timeout = 0;
+ int status;
+ unsigned u;
/* fail completely if get null pointers passed */
SMB_ASSERT(fn && keystr_pattern);
@@ -335,7 +343,11 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time
entry = SMB_STRNDUP(databuf.dptr, databuf.dsize);
SAFE_FREE(databuf.dptr);
valstr = SMB_MALLOC(databuf.dsize - TIMEOUT_LEN);
- sscanf(entry, CACHE_DATA_FMT, (int*)(&timeout), valstr);
+ status = sscanf(entry, CACHE_DATA_FMT, &u, valstr);
+ if ( status != 2 ) {
+ DEBUG(0,("gencache_iterate: invalid return from sscanf %d\n",status));
+ }
+ timeout = u;
DEBUG(10, ("Calling function with arguments (key = %s, value = %s, timeout = %s)\n",
keystr, valstr, ctime(&timeout)));
diff --git a/source3/lib/genrand.c b/source3/lib/genrand.c
index 9ccddfa4c5..f37bbc9c2f 100644
--- a/source3/lib/genrand.c
+++ b/source3/lib/genrand.c
@@ -22,7 +22,7 @@
#include "includes.h"
-static unsigned char hash[258];
+static unsigned char smb_arc4_state[258];
static uint32 counter;
static BOOL done_reseed = False;
@@ -52,61 +52,6 @@ static void get_rand_reseed_data(int *reseed_data)
}
}
-/****************************************************************
- Setup the seed.
-*****************************************************************/
-
-static void seed_random_stream(unsigned char *seedval, size_t seedlen)
-{
- unsigned char j = 0;
- size_t ind;
-
- for (ind = 0; ind < 256; ind++)
- hash[ind] = (unsigned char)ind;
-
- for( ind = 0; ind < 256; ind++) {
- unsigned char tc;
-
- j += (hash[ind] + seedval[ind%seedlen]);
-
- tc = hash[ind];
- hash[ind] = hash[j];
- hash[j] = tc;
- }
-
- hash[256] = 0;
- hash[257] = 0;
-}
-
-/****************************************************************
- Get datasize bytes worth of random data.
-*****************************************************************/
-
-static void get_random_stream(unsigned char *data, size_t datasize)
-{
- unsigned char index_i = hash[256];
- unsigned char index_j = hash[257];
- size_t ind;
-
- for( ind = 0; ind < datasize; ind++) {
- unsigned char tc;
- unsigned char t;
-
- index_i++;
- index_j += hash[index_i];
-
- tc = hash[index_i];
- hash[index_i] = hash[index_j];
- hash[index_j] = tc;
-
- t = hash[index_i] + hash[index_j];
- data[ind] = hash[t];
- }
-
- hash[256] = index_i;
- hash[257] = index_j;
-}
-
/****************************************************************
Get a 16 byte hash from the contents of a file.
Note that the hash is not initialised.
@@ -202,7 +147,7 @@ static int do_reseed(BOOL use_fd, int fd)
seed_inbuf[i] ^= ((char *)(&reseed_data))[i % sizeof(reseed_data)];
}
- seed_random_stream(seed_inbuf, sizeof(seed_inbuf));
+ smb_arc4_init(smb_arc4_state, seed_inbuf, sizeof(seed_inbuf));
return -1;
}
@@ -246,7 +191,7 @@ void generate_random_buffer( unsigned char *out, int len)
while(len > 0) {
int copy_len = len > 16 ? 16 : len;
- get_random_stream(md4_buf, sizeof(md4_buf));
+ smb_arc4_crypt(smb_arc4_state, md4_buf, sizeof(md4_buf));
mdfour(tmp_buf, md4_buf, sizeof(md4_buf));
memcpy(p, tmp_buf, copy_len);
p += copy_len;
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
index 7d3addd86a..058bbc99b0 100644
--- a/source3/lib/messages.c
+++ b/source3/lib/messages.c
@@ -57,8 +57,8 @@ static int received_signal;
struct message_rec {
int msg_version;
int msg_type;
- pid_t dest;
- pid_t src;
+ struct process_id dest;
+ struct process_id src;
size_t len;
};
@@ -66,7 +66,7 @@ struct message_rec {
static struct dispatch_fns {
struct dispatch_fns *next, *prev;
int msg_type;
- void (*fn)(int msg_type, pid_t pid, void *buf, size_t len);
+ void (*fn)(int msg_type, struct process_id pid, void *buf, size_t len);
} *dispatch_fns;
/****************************************************************************
@@ -83,10 +83,12 @@ static void sig_usr1(void)
A useful function for testing the message system.
****************************************************************************/
-static void ping_message(int msg_type, pid_t src, void *buf, size_t len)
+static void ping_message(int msg_type, struct process_id src,
+ void *buf, size_t len)
{
const char *msg = buf ? buf : "none";
- DEBUG(1,("INFO: Received PING message from PID %u [%s]\n",(unsigned int)src, msg));
+ DEBUG(1,("INFO: Received PING message from PID %s [%s]\n",
+ procid_str_static(&src), msg));
message_send_pid(src, MSG_PONG, buf, len, True);
}
@@ -123,12 +125,12 @@ BOOL message_init(void)
Form a static tdb key from a pid.
******************************************************************/
-static TDB_DATA message_key_pid(pid_t pid)
+static TDB_DATA message_key_pid(struct process_id pid)
{
static char key[20];
TDB_DATA kbuf;
- slprintf(key, sizeof(key)-1, "PID/%d", (int)pid);
+ slprintf(key, sizeof(key)-1, "PID/%s", procid_str_static(&pid));
kbuf.dptr = (char *)key;
kbuf.dsize = strlen(key)+1;
@@ -140,8 +142,9 @@ static TDB_DATA message_key_pid(pid_t pid)
then delete its record in the database.
****************************************************************************/
-static BOOL message_notify(pid_t pid)
+static BOOL message_notify(struct process_id procid)
{
+ pid_t pid = procid.pid;
/*
* Doing kill with a non-positive pid causes messages to be
* sent to places we don't want.
@@ -152,7 +155,7 @@ static BOOL message_notify(pid_t pid)
if (kill(pid, SIGUSR1) == -1) {
if (errno == ESRCH) {
DEBUG(2,("pid %d doesn't exist - deleting messages record\n", (int)pid));
- tdb_delete(tdb, message_key_pid(pid));
+ tdb_delete(tdb, message_key_pid(procid));
} else {
DEBUG(2,("message to process %d failed - %s\n", (int)pid, strerror(errno)));
}
@@ -165,8 +168,10 @@ static BOOL message_notify(pid_t pid)
Send a message to a particular pid.
****************************************************************************/
-static BOOL message_send_pid_internal(pid_t pid, int msg_type, const void *buf, size_t len,
- BOOL duplicates_allowed, unsigned int timeout)
+static BOOL message_send_pid_internal(struct process_id pid, int msg_type,
+ const void *buf, size_t len,
+ BOOL duplicates_allowed,
+ unsigned int timeout)
{
TDB_DATA kbuf;
TDB_DATA dbuf;
@@ -180,12 +185,12 @@ static BOOL message_send_pid_internal(pid_t pid, int msg_type, const void *buf,
* sent to places we don't want.
*/
- SMB_ASSERT(pid > 0);
+ SMB_ASSERT(procid_to_pid(&pid) > 0);
rec.msg_version = MESSAGE_VERSION;
rec.msg_type = msg_type;
rec.dest = pid;
- rec.src = sys_getpid();
+ rec.src = procid_self();
rec.len = len;
kbuf = message_key_pid(pid);
@@ -288,7 +293,7 @@ static BOOL message_send_pid_internal(pid_t pid, int msg_type, const void *buf,
Send a message to a particular pid - no timeout.
****************************************************************************/
-BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len, BOOL duplicates_allowed)
+BOOL message_send_pid(struct process_id pid, int msg_type, const void *buf, size_t len, BOOL duplicates_allowed)
{
return message_send_pid_internal(pid, msg_type, buf, len, duplicates_allowed, 0);
}
@@ -297,7 +302,7 @@ BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len, BOOL
Send a message to a particular pid, with timeout in seconds.
****************************************************************************/
-BOOL message_send_pid_with_timeout(pid_t pid, int msg_type, const void *buf, size_t len,
+BOOL message_send_pid_with_timeout(struct process_id pid, int msg_type, const void *buf, size_t len,
BOOL duplicates_allowed, unsigned int timeout)
{
return message_send_pid_internal(pid, msg_type, buf, len, duplicates_allowed, timeout);
@@ -307,7 +312,7 @@ BOOL message_send_pid_with_timeout(pid_t pid, int msg_type, const void *buf, siz
Count the messages pending for a particular pid. Expensive....
****************************************************************************/
-unsigned int messages_pending_for_pid(pid_t pid)
+unsigned int messages_pending_for_pid(struct process_id pid)
{
TDB_DATA kbuf;
TDB_DATA dbuf;
@@ -349,7 +354,7 @@ static BOOL retrieve_all_messages(char **msgs_buf, size_t *total_len)
*msgs_buf = NULL;
*total_len = 0;
- kbuf = message_key_pid(sys_getpid());
+ kbuf = message_key_pid(pid_to_procid(sys_getpid()));
if (tdb_chainlock(tdb, kbuf) == -1)
return False;
@@ -377,7 +382,8 @@ static BOOL retrieve_all_messages(char **msgs_buf, size_t *total_len)
Parse out the next message for the current process.
****************************************************************************/
-static BOOL message_recv(char *msgs_buf, size_t total_len, int *msg_type, pid_t *src, char **buf, size_t *len)
+static BOOL message_recv(char *msgs_buf, size_t total_len, int *msg_type,
+ struct process_id *src, char **buf, size_t *len)
{
struct message_rec rec;
char *ret_buf = *buf;
@@ -420,7 +426,7 @@ static BOOL message_recv(char *msgs_buf, size_t total_len, int *msg_type, pid_t
void message_dispatch(void)
{
int msg_type;
- pid_t src;
+ struct process_id src;
char *buf;
char *msgs_buf;
size_t len, total_len;
@@ -438,8 +444,9 @@ void message_dispatch(void)
return;
for (buf = msgs_buf; message_recv(msgs_buf, total_len, &msg_type, &src, &buf, &len); buf += len) {
- DEBUG(10,("message_dispatch: received msg_type=%d src_pid=%u\n",
- msg_type, (unsigned int) src));
+ DEBUG(10,("message_dispatch: received msg_type=%d "
+ "src_pid=%u\n", msg_type,
+ (unsigned int) procid_to_pid(&src)));
n_handled = 0;
for (dfn = dispatch_fns; dfn; dfn = dfn->next) {
if (dfn->msg_type == msg_type) {
@@ -464,7 +471,8 @@ void message_dispatch(void)
****************************************************************************/
void message_register(int msg_type,
- void (*fn)(int msg_type, pid_t pid, void *buf, size_t len))
+ void (*fn)(int msg_type, struct process_id pid,
+ void *buf, size_t len))
{
struct dispatch_fns *dfn;
@@ -543,8 +551,9 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void
/* If the pid was not found delete the entry from connections.tdb */
if (errno == ESRCH) {
- DEBUG(2,("pid %u doesn't exist - deleting connections %d [%s]\n",
- (unsigned int)crec.pid, crec.cnum, crec.name));
+ DEBUG(2,("pid %s doesn't exist - deleting connections %d [%s]\n",
+ procid_str_static(&crec.pid),
+ crec.cnum, crec.name));
tdb_delete(the_tdb, kbuf);
}
}
diff --git a/source3/lib/module.c b/source3/lib/module.c
index 49121d12ca..885faf8d80 100644
--- a/source3/lib/module.c
+++ b/source3/lib/module.c
@@ -231,77 +231,3 @@ void smb_run_idle_events(time_t now)
return;
}
-
-/***************************************************************************
- * This Function registers a exit event
- *
- * the registered functions are run on exit()
- * and maybe shutdown idle connections (e.g. to an LDAP server)
- ***************************************************************************/
-
-struct smb_exit_list_ent {
- struct smb_exit_list_ent *prev,*next;
- smb_event_id_t id;
- smb_exit_event_fn *fn;
- void *data;
-};
-
-static struct smb_exit_list_ent *smb_exit_event_list = NULL;
-
-smb_event_id_t smb_register_exit_event(smb_exit_event_fn *fn, void *data)
-{
- struct smb_exit_list_ent *event;
- static smb_event_id_t smb_exit_event_id = 1;
-
- if (!fn) {
- return SMB_EVENT_ID_INVALID;
- }
-
- event = SMB_MALLOC_P(struct smb_exit_list_ent);
- if (!event) {
- DEBUG(0,("malloc() failed!\n"));
- return SMB_EVENT_ID_INVALID;
- }
- event->fn = fn;
- event->data = data;
- event->id = smb_exit_event_id++;
-
- DLIST_ADD(smb_exit_event_list,event);
-
- return event->id;
-}
-
-BOOL smb_unregister_exit_event(smb_event_id_t id)
-{
- struct smb_exit_list_ent *event = smb_exit_event_list;
-
- while(event) {
- if (event->id == id) {
- DLIST_REMOVE(smb_exit_event_list,event);
- SAFE_FREE(event);
- return True;
- }
- event = event->next;
- }
-
- return False;
-}
-
-void smb_run_exit_events(void)
-{
- struct smb_exit_list_ent *event = smb_exit_event_list;
- struct smb_exit_list_ent *tmp = NULL;
-
- while (event) {
- event->fn(&event->data);
- tmp = event;
- event = event->next;
- /* exit event should only run one time :-)*/
- SAFE_FREE(tmp);
- }
-
- /* the list is empty now...*/
- smb_exit_event_list = NULL;
-
- return;
-}
diff --git a/source3/lib/pidfile.c b/source3/lib/pidfile.c
index 20a8e82ce2..b041eb7f1b 100644
--- a/source3/lib/pidfile.c
+++ b/source3/lib/pidfile.c
@@ -57,7 +57,7 @@ pid_t pidfile_pid(const char *name)
goto noproc;
}
- if (!process_exists((pid_t)ret)) {
+ if (!process_exists_by_pid(ret)) {
goto noproc;
}
diff --git a/source3/lib/privileges.c b/source3/lib/privileges.c
index d95c1ba4c1..ff0631b82f 100644
--- a/source3/lib/privileges.c
+++ b/source3/lib/privileges.c
@@ -397,6 +397,8 @@ static BOOL privilege_set_add(PRIVILEGE_SET *priv_set, LUID_ATTR set)
/*********************************************************************
Generate the LUID_ATTR structure based on a bitmask
+ The assumption here is that the privilege has already been validated
+ so we are guaranteed to find it in the list.
*********************************************************************/
LUID_ATTR get_privilege_luid( SE_PRIV *mask )
@@ -404,8 +406,7 @@ LUID_ATTR get_privilege_luid( SE_PRIV *mask )
LUID_ATTR priv_luid;
int i;
- priv_luid.attr = 0;
- priv_luid.luid.high = 0;
+ ZERO_STRUCT( priv_luid );
for ( i=0; !se_priv_equal(&privs[i].se_priv, &se_priv_end); i++ ) {
diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c
index cf7c8fc87f..f08a67a22c 100644
--- a/source3/lib/smbldap.c
+++ b/source3/lib/smbldap.c
@@ -267,7 +267,11 @@ ATTRIB_MAP_ENTRY sidmap_attr_list[] = {
return;
while ( list[i] ) {
- SAFE_FREE( list[i] );
+ /* SAFE_FREE generates a warning here that can't be gotten rid
+ * of with CONST_DISCARD */
+ if (list[i] != NULL) {
+ free(CONST_DISCARD(char *, list[i]));
+ }
i+=1;
}
diff --git a/source3/lib/smbldap_util.c b/source3/lib/smbldap_util.c
index 798cb3fff7..4679b86487 100644
--- a/source3/lib/smbldap_util.c
+++ b/source3/lib/smbldap_util.c
@@ -27,6 +27,65 @@
#include "smbldap.h"
/**********************************************************************
+ Add the account-policies below the sambaDomain object to LDAP,
+*********************************************************************/
+static NTSTATUS add_new_domain_account_policies(struct smbldap_state *ldap_state,
+ const char *domain_name)
+{
+ NTSTATUS ntstatus = NT_STATUS_UNSUCCESSFUL;
+ int i, rc;
+ uint32 policy_default;
+ const char *policy_attr = NULL;
+ pstring dn;
+ LDAPMod **mods = NULL;
+
+ DEBUG(3,("Adding new account policies for domain\n"));
+
+ pstr_sprintf(dn, "%s=%s,%s",
+ get_attr_key2string(dominfo_attr_list, LDAP_ATTR_DOMAIN),
+ domain_name, lp_ldap_suffix());
+
+ for (i=1; decode_account_policy_name(i) != NULL; i++) {
+
+ pstring val;
+
+ policy_attr = get_account_policy_attr(i);
+ if (!policy_attr) {
+ DEBUG(0,("add_new_domain_account_policies: ops. no policy!\n"));
+ continue;
+ }
+
+ if (!account_policy_get_default(i, &policy_default)) {
+ DEBUG(0,("add_new_domain_account_policies: failed to get default account policy\n"));
+ return ntstatus;
+ }
+
+ DEBUG(10,("add_new_domain_account_policies: adding \"%s\" with value: %d\n", policy_attr, policy_default));
+
+ pstr_sprintf(val, "%d", policy_default);
+
+ smbldap_set_mod( &mods, LDAP_MOD_REPLACE, policy_attr, val);
+
+ rc = smbldap_modify(ldap_state, dn, mods);
+
+ if (rc!=LDAP_SUCCESS) {
+ char *ld_error = NULL;
+ ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING, &ld_error);
+ DEBUG(1,("failed to add account policies to dn= %s with: %s\n\t%s\n",
+ dn, ldap_err2string(rc),
+ ld_error ? ld_error : "unknown"));
+ SAFE_FREE(ld_error);
+ ldap_mods_free(mods, True);
+ return ntstatus;
+ }
+ }
+
+ ldap_mods_free(mods, True);
+
+ return NT_STATUS_OK;
+}
+
+/**********************************************************************
Add the sambaDomain to LDAP, so we don't have to search for this stuff
again. This is a once-add operation for now.
@@ -200,6 +259,13 @@ NTSTATUS smbldap_search_domain_info(struct smbldap_state *ldap_state,
goto failed;
}
+ status = add_new_domain_account_policies(ldap_state, domain_name);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("Adding domain account policies for %s failed with %s\n",
+ domain_name, nt_errstr(status)));
+ goto failed;
+ }
+
return smbldap_search_domain_info(ldap_state, result, domain_name, False);
}
diff --git a/source3/lib/smbrun.c b/source3/lib/smbrun.c
index 13e330dd97..6d6d7817f1 100644
--- a/source3/lib/smbrun.c
+++ b/source3/lib/smbrun.c
@@ -225,10 +225,16 @@ int smbrunsecret(const char *cmd, const char *secret)
*/
int status = 0;
pid_t wpid;
+ size_t towrite;
+ ssize_t wrote;
close(ifd[0]);
/* send the secret */
- write(ifd[1], secret, strlen(secret));
+ towrite = strlen(secret);
+ wrote = write(ifd[1], secret, towrite);
+ if ( wrote != towrite ) {
+ DEBUG(0,("smbrunsecret: wrote %ld of %lu bytes\n",(long)wrote,(unsigned long)towrite));
+ }
fsync(ifd[1]);
close(ifd[1]);
diff --git a/source3/lib/tallocmsg.c b/source3/lib/tallocmsg.c
index 8ee3c257f6..8f03fd66ff 100644
--- a/source3/lib/tallocmsg.c
+++ b/source3/lib/tallocmsg.c
@@ -30,7 +30,7 @@
* Respond to a POOL_USAGE message by sending back string form of memory
* usage stats.
**/
-void msg_pool_usage(int msg_type, pid_t src_pid,
+void msg_pool_usage(int msg_type, struct process_id src_pid,
void *UNUSED(buf), size_t UNUSED(len))
{
off_t reply;
@@ -41,7 +41,7 @@ void msg_pool_usage(int msg_type, pid_t src_pid,
DEBUG(2,("Got POOL_USAGE\n"));
reply = talloc_total_size(NULL);
- fstr_sprintf(reply_str, "%lld", reply);
+ fstr_sprintf(reply_str, "%ld", (long)reply);
message_send_pid(src_pid, MSG_POOL_USAGE,
reply_str, strlen(reply_str)+1, True);
diff --git a/source3/lib/time.c b/source3/lib/time.c
index 5e0f5646fc..385762e82c 100644
--- a/source3/lib/time.c
+++ b/source3/lib/time.c
@@ -783,6 +783,15 @@ BOOL nt_time_is_zero(NTTIME *nt)
}
/****************************************************************************
+ Check if two NTTIMEs are the same.
+****************************************************************************/
+
+BOOL nt_time_equals(NTTIME *nt1, NTTIME *nt2)
+{
+ return (nt1->high == nt2->high && nt1->low == nt2->low);
+}
+
+/****************************************************************************
Return a timeval difference in usec.
****************************************************************************/
@@ -792,6 +801,135 @@ SMB_BIG_INT usec_time_diff(const struct timeval *larget, const struct timeval *s
return (sec_diff * 1000000) + (SMB_BIG_INT)(larget->tv_usec - smallt->tv_usec);
}
+/*
+ return a timeval struct with the given elements
+*/
+struct timeval timeval_set(uint32_t secs, uint32_t usecs)
+{
+ struct timeval tv;
+ tv.tv_sec = secs;
+ tv.tv_usec = usecs;
+ return tv;
+}
+
+/*
+ return a zero timeval
+*/
+struct timeval timeval_zero(void)
+{
+ return timeval_set(0,0);
+}
+
+/*
+ return True if a timeval is zero
+*/
+BOOL timeval_is_zero(const struct timeval *tv)
+{
+ return tv->tv_sec == 0 && tv->tv_usec == 0;
+}
+
+/*
+ return a timeval for the current time
+*/
+struct timeval timeval_current(void)
+{
+ struct timeval tv;
+ GetTimeOfDay(&tv);
+ return tv;
+}
+
+/*
+ return a timeval ofs microseconds after tv
+*/
+struct timeval timeval_add(const struct timeval *tv,
+ uint32_t secs, uint32_t usecs)
+{
+ struct timeval tv2 = *tv;
+ tv2.tv_sec += secs;
+ tv2.tv_usec += usecs;
+ tv2.tv_sec += tv2.tv_usec / 1000000;
+ tv2.tv_usec = tv2.tv_usec % 1000000;
+ return tv2;
+}
+
+/*
+ return the sum of two timeval structures
+*/
+struct timeval timeval_sum(const struct timeval *tv1,
+ const struct timeval *tv2)
+{
+ return timeval_add(tv1, tv2->tv_sec, tv2->tv_usec);
+}
+
+/*
+ return a timeval secs/usecs into the future
+*/
+struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs)
+{
+ struct timeval tv = timeval_current();
+ return timeval_add(&tv, secs, usecs);
+}
+
+/*
+ compare two timeval structures.
+ Return -1 if tv1 < tv2
+ Return 0 if tv1 == tv2
+ Return 1 if tv1 > tv2
+*/
+int timeval_compare(const struct timeval *tv1, const struct timeval *tv2)
+{
+ if (tv1->tv_sec > tv2->tv_sec) return 1;
+ if (tv1->tv_sec < tv2->tv_sec) return -1;
+ if (tv1->tv_usec > tv2->tv_usec) return 1;
+ if (tv1->tv_usec < tv2->tv_usec) return -1;
+ return 0;
+}
+
+/*
+ return the difference between two timevals as a timeval
+ if tv1 comes after tv2, then return a zero timeval
+ (this is *tv2 - *tv1)
+*/
+struct timeval timeval_until(const struct timeval *tv1,
+ const struct timeval *tv2)
+{
+ struct timeval t;
+ if (timeval_compare(tv1, tv2) >= 0) {
+ return timeval_zero();
+ }
+ t.tv_sec = tv2->tv_sec - tv1->tv_sec;
+ if (tv1->tv_usec > tv2->tv_usec) {
+ t.tv_sec--;
+ t.tv_usec = 1000000 - (tv1->tv_usec - tv2->tv_usec);
+ } else {
+ t.tv_usec = tv2->tv_usec - tv1->tv_usec;
+ }
+ return t;
+}
+
+/*
+ return the lesser of two timevals
+*/
+struct timeval timeval_min(const struct timeval *tv1,
+ const struct timeval *tv2)
+{
+ if (tv1->tv_sec < tv2->tv_sec) return *tv1;
+ if (tv1->tv_sec > tv2->tv_sec) return *tv2;
+ if (tv1->tv_usec < tv2->tv_usec) return *tv1;
+ return *tv2;
+}
+
+/*
+ return the greater of two timevals
+*/
+struct timeval timeval_max(const struct timeval *tv1,
+ const struct timeval *tv2)
+{
+ if (tv1->tv_sec > tv2->tv_sec) return *tv1;
+ if (tv1->tv_sec < tv2->tv_sec) return *tv2;
+ if (tv1->tv_usec > tv2->tv_usec) return *tv1;
+ return *tv2;
+}
/****************************************************************************
convert ASN.1 GeneralizedTime string to unix-time
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 3993892196..a5cfe95b66 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -1404,12 +1404,22 @@ BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask)
Check if a process exists. Does this work on all unixes?
****************************************************************************/
-BOOL process_exists(pid_t pid)
+BOOL process_exists(const struct process_id pid)
{
+ if (!procid_is_local(&pid)) {
+ /* This *SEVERELY* needs fixing. */
+ return True;
+ }
+
/* Doing kill with a non-positive pid causes messages to be
* sent to places we don't want. */
- SMB_ASSERT(pid > 0);
- return(kill(pid,0) == 0 || errno != ESRCH);
+ SMB_ASSERT(pid.pid > 0);
+ return(kill(pid.pid,0) == 0 || errno != ESRCH);
+}
+
+BOOL process_exists_by_pid(pid_t pid)
+{
+ return process_exists(pid_to_procid(pid));
}
/*******************************************************************
@@ -2756,3 +2766,57 @@ uint32 map_share_mode_to_deny_mode(uint32 share_access, uint32 private_options)
return (uint32)-1;
}
+
+pid_t procid_to_pid(const struct process_id *proc)
+{
+ return proc->pid;
+}
+
+struct process_id pid_to_procid(pid_t pid)
+{
+ struct process_id result;
+ result.pid = pid;
+ return result;
+}
+
+struct process_id procid_self(void)
+{
+ return pid_to_procid(sys_getpid());
+}
+
+BOOL procid_equal(const struct process_id *p1, const struct process_id *p2)
+{
+ return (p1->pid == p2->pid);
+}
+
+BOOL procid_is_me(const struct process_id *pid)
+{
+ return (pid->pid == sys_getpid());
+}
+
+struct process_id interpret_pid(const char *pid_string)
+{
+ return pid_to_procid(atoi(pid_string));
+}
+
+char *procid_str_static(const struct process_id *pid)
+{
+ static fstring str;
+ fstr_sprintf(str, "%d", pid->pid);
+ return str;
+}
+
+char *procid_str(TALLOC_CTX *mem_ctx, const struct process_id *pid)
+{
+ return talloc_strdup(mem_ctx, procid_str_static(pid));
+}
+
+BOOL procid_valid(const struct process_id *pid)
+{
+ return (pid->pid != -1);
+}
+
+BOOL procid_is_local(const struct process_id *pid)
+{
+ return True;
+}