summaryrefslogtreecommitdiff
path: root/source3/lib
diff options
context:
space:
mode:
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/dbwrap.c26
-rw-r--r--source3/lib/dbwrap_tdb.c12
-rw-r--r--source3/lib/display_sec.c8
-rw-r--r--source3/lib/events.c2
-rw-r--r--source3/lib/fault.c174
-rw-r--r--source3/lib/file_id.c47
-rw-r--r--source3/lib/ldap_debug_handler.c4
-rw-r--r--source3/lib/secdesc.c63
-rw-r--r--source3/lib/smbconf/smbconf_reg.c177
-rw-r--r--source3/lib/smbldap.c2
-rw-r--r--source3/lib/system.c32
-rw-r--r--source3/lib/tdb_validate.c5
-rw-r--r--source3/lib/util.c173
-rw-r--r--source3/lib/util_sock.c104
-rw-r--r--source3/lib/util_str.c112
-rw-r--r--source3/lib/wb_reqtrans.c401
-rw-r--r--source3/lib/wbclient.c62
17 files changed, 547 insertions, 857 deletions
diff --git a/source3/lib/dbwrap.c b/source3/lib/dbwrap.c
index a57b7c97a5..5e7ce6099f 100644
--- a/source3/lib/dbwrap.c
+++ b/source3/lib/dbwrap.c
@@ -42,6 +42,29 @@ static int dbwrap_fallback_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
return 0;
}
+/*
+ * Fall back using fetch if no genuine parse operation is provided
+ */
+
+static int dbwrap_fallback_parse_record(struct db_context *db, TDB_DATA key,
+ int (*parser)(TDB_DATA key,
+ TDB_DATA data,
+ void *private_data),
+ void *private_data)
+{
+ TDB_DATA data;
+ int res;
+
+ res = db->fetch(db, talloc_tos(), key, &data);
+ if (res != 0) {
+ return res;
+ }
+
+ res = parser(key, data, private_data);
+ TALLOC_FREE(data.dptr);
+ return res;
+}
+
/**
* open a database
*/
@@ -101,6 +124,9 @@ struct db_context *db_open(TALLOC_CTX *mem_ctx,
if ((result != NULL) && (result->fetch == NULL)) {
result->fetch = dbwrap_fallback_fetch;
}
+ if ((result != NULL) && (result->parse_record == NULL)) {
+ result->parse_record = dbwrap_fallback_parse_record;
+ }
return result;
}
diff --git a/source3/lib/dbwrap_tdb.c b/source3/lib/dbwrap_tdb.c
index b5eb1881d4..c71e073b41 100644
--- a/source3/lib/dbwrap_tdb.c
+++ b/source3/lib/dbwrap_tdb.c
@@ -176,6 +176,17 @@ static int db_tdb_fetch(struct db_context *db, TALLOC_CTX *mem_ctx,
return 0;
}
+static int db_tdb_parse(struct db_context *db, TDB_DATA key,
+ int (*parser)(TDB_DATA key, TDB_DATA data,
+ void *private_data),
+ void *private_data)
+{
+ struct db_tdb_ctx *ctx = talloc_get_type_abort(
+ db->private_data, struct db_tdb_ctx);
+
+ return tdb_parse_record(ctx->wtdb->tdb, key, parser, private_data);
+}
+
static NTSTATUS db_tdb_store(struct db_record *rec, TDB_DATA data, int flag)
{
struct db_tdb_ctx *ctx = talloc_get_type_abort(rec->private_data,
@@ -351,6 +362,7 @@ struct db_context *db_open_tdb(TALLOC_CTX *mem_ctx,
result->fetch = db_tdb_fetch;
result->traverse = db_tdb_traverse;
result->traverse_read = db_tdb_traverse_read;
+ result->parse_record = db_tdb_parse;
result->get_seqnum = db_tdb_get_seqnum;
result->get_flags = db_tdb_get_flags;
result->persistent = ((tdb_flags & TDB_CLEAR_IF_FIRST) == 0);
diff --git a/source3/lib/display_sec.c b/source3/lib/display_sec.c
index 636639c11d..fe1ae77edd 100644
--- a/source3/lib/display_sec.c
+++ b/source3/lib/display_sec.c
@@ -155,13 +155,13 @@ void display_sec_ace_flags(uint8_t flags)
****************************************************************************/
static void disp_sec_ace_object(struct security_ace_object *object)
{
- if (object->flags & SEC_ACE_OBJECT_PRESENT) {
- printf("Object type: SEC_ACE_OBJECT_PRESENT\n");
+ if (object->flags & SEC_ACE_OBJECT_TYPE_PRESENT) {
+ printf("Object type: SEC_ACE_OBJECT_TYPE_PRESENT\n");
printf("Object GUID: %s\n", GUID_string(talloc_tos(),
&object->type.type));
}
- if (object->flags & SEC_ACE_OBJECT_INHERITED_PRESENT) {
- printf("Object type: SEC_ACE_OBJECT_INHERITED_PRESENT\n");
+ if (object->flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) {
+ printf("Object type: SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT\n");
printf("Object GUID: %s\n", GUID_string(talloc_tos(),
&object->inherited_type.inherited_type));
}
diff --git a/source3/lib/events.c b/source3/lib/events.c
index 44b4562757..9e81a47796 100644
--- a/source3/lib/events.c
+++ b/source3/lib/events.c
@@ -282,7 +282,7 @@ static void s3_event_debug(void *context, enum tevent_debug_level level,
samba_level = 2;
break;
case TEVENT_DEBUG_TRACE:
- samba_level = 5;
+ samba_level = 10;
break;
};
diff --git a/source3/lib/fault.c b/source3/lib/fault.c
index a1530987f3..efd1dddfd4 100644
--- a/source3/lib/fault.c
+++ b/source3/lib/fault.c
@@ -2,6 +2,7 @@
Unix SMB/CIFS implementation.
Critical Fault handling
Copyright (C) Andrew Tridgell 1992-1998
+ Copyright (C) Tim Prouty 2009
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
@@ -87,6 +88,128 @@ void fault_setup(void (*fn)(void *))
#endif
}
+/**
+ * Build up the default corepath as "<logbase>/cores/<progname>"
+ */
+static char *get_default_corepath(const char *logbase, const char *progname)
+{
+ char *tmp_corepath;
+
+ /* Setup core dir in logbase. */
+ tmp_corepath = talloc_asprintf(NULL, "%s/cores", logbase);
+ if (!tmp_corepath)
+ return NULL;
+
+ if ((mkdir(tmp_corepath, 0700) == -1) && errno != EEXIST)
+ goto err_out;
+
+ if (chmod(tmp_corepath, 0700) == -1)
+ goto err_out;
+
+ talloc_free(tmp_corepath);
+
+ /* Setup progname-specific core subdir */
+ tmp_corepath = talloc_asprintf(NULL, "%s/cores/%s", logbase, progname);
+ if (!tmp_corepath)
+ return NULL;
+
+ if (mkdir(tmp_corepath, 0700) == -1 && errno != EEXIST)
+ goto err_out;
+
+ if (chown(tmp_corepath, getuid(), getgid()) == -1)
+ goto err_out;
+
+ if (chmod(tmp_corepath, 0700) == -1)
+ goto err_out;
+
+ return tmp_corepath;
+
+ err_out:
+ talloc_free(tmp_corepath);
+ return NULL;
+}
+
+/**
+ * Get the FreeBSD corepath.
+ *
+ * On FreeBSD the current working directory is ignored when creating a core
+ * file. Instead the core directory is controlled via sysctl. This consults
+ * the value of "kern.corefile" so the correct corepath can be printed out
+ * before dump_core() calls abort.
+ */
+#if (defined(FREEBSD) && defined(HAVE_SYSCTLBYNAME))
+static char *get_freebsd_corepath(void)
+{
+ char *tmp_corepath = NULL;
+ char *end = NULL;
+ size_t len = 128;
+ int ret;
+
+ /* Loop with increasing sizes so we don't allocate too much. */
+ do {
+ if (len > 1024) {
+ goto err_out;
+ }
+
+ tmp_corepath = (char *)talloc_realloc(NULL, tmp_corepath,
+ char, len);
+ if (!tmp_corepath) {
+ return NULL;
+ }
+
+ ret = sysctlbyname("kern.corefile", tmp_corepath, &len, NULL,
+ 0);
+ if (ret == -1) {
+ if (errno != ENOMEM) {
+ DEBUG(0, ("sysctlbyname failed getting "
+ "kern.corefile %s\n",
+ strerror(errno)));
+ goto err_out;
+ }
+
+ /* Not a large enough array, try a bigger one. */
+ len = len << 1;
+ }
+ } while (ret == -1);
+
+ /* Strip off the common filename expansion */
+ if ((end = strrchr_m(tmp_corepath, '/'))) {
+ *end = '\0';
+ }
+
+ return tmp_corepath;
+
+ err_out:
+ if (tmp_corepath) {
+ talloc_free(tmp_corepath);
+ }
+ return NULL;
+}
+#endif
+
+/**
+ * Try getting system-specific corepath if one exists.
+ *
+ * If the system doesn't define a corepath, then the default is used.
+ */
+static char *get_corepath(const char *logbase, const char *progname)
+{
+ char *tmp_corepath = NULL;
+
+ /* @todo: Add support for the linux corepath. */
+#if (defined(FREEBSD) && defined(HAVE_SYSCTLBYNAME))
+ tmp_corepath = get_freebsd_corepath();
+#endif
+
+ /* If this has been set correctly, we're done. */
+ if (tmp_corepath) {
+ return tmp_corepath;
+ }
+
+ /* Fall back to the default. */
+ return get_default_corepath(logbase, progname);
+}
+
/*******************************************************************
make all the preparations to safely dump a core file
********************************************************************/
@@ -104,7 +227,7 @@ void dump_core_setup(const char *progname)
*end = '\0';
}
} else {
- /* We will end up here is the log file is given on the command
+ /* We will end up here if the log file is given on the command
* line by the -l option but the "log file" option is not set
* in smb.conf.
*/
@@ -115,50 +238,13 @@ void dump_core_setup(const char *progname)
SMB_ASSERT(progname != NULL);
- if (asprintf(&corepath, "%s/cores", logbase) < 0) {
- SAFE_FREE(logbase);
- return;
- }
- if (mkdir(corepath,0700) == -1) {
- if (errno != EEXIST) {
- SAFE_FREE(corepath);
- SAFE_FREE(logbase);
- return;
- }
- }
- if (chmod(corepath,0700) == -1) {
- SAFE_FREE(corepath);
- SAFE_FREE(logbase);
- return;
- }
-
- SAFE_FREE(corepath);
- if (asprintf(&corepath, "%s/cores/%s",
- logbase, progname) < 0) {
- SAFE_FREE(logbase);
- return;
- }
- if (mkdir(corepath,0700) == -1) {
- if (errno != EEXIST) {
- SAFE_FREE(corepath);
- SAFE_FREE(logbase);
- return;
- }
- }
-
- if (chown(corepath,getuid(),getgid()) == -1) {
- SAFE_FREE(corepath);
- SAFE_FREE(logbase);
- return;
- }
- if (chmod(corepath,0700) == -1) {
- SAFE_FREE(corepath);
- SAFE_FREE(logbase);
- return;
+ corepath = get_corepath(logbase, progname);
+ if (!corepath) {
+ DEBUG(0, ("Unable to setup corepath for %s: %s\n", progname,
+ strerror(errno)));
+ goto out;
}
- SAFE_FREE(corepath);
- SAFE_FREE(logbase);
#ifdef HAVE_GETRLIMIT
#ifdef RLIMIT_CORE
@@ -185,6 +271,8 @@ void dump_core_setup(const char *progname)
/* FIXME: if we have a core-plus-pid facility, configurably set
* this up here.
*/
+ out:
+ SAFE_FREE(logbase);
}
void dump_core(void)
diff --git a/source3/lib/file_id.c b/source3/lib/file_id.c
index 0633d4b88d..0902e3d224 100644
--- a/source3/lib/file_id.c
+++ b/source3/lib/file_id.c
@@ -22,26 +22,11 @@
#include "includes.h"
/*
- return a file_id which gives a unique ID for a file given the device and
- inode numbers
- */
-struct file_id file_id_create_dev(SMB_DEV_T dev, SMB_INO_T inode)
-{
- struct file_id key;
- /* the ZERO_STRUCT ensures padding doesn't break using the key as a
- * blob */
- ZERO_STRUCT(key);
- key.devid = dev;
- key.inode = inode;
- return key;
-}
-
-/*
generate a file_id from a stat structure
*/
struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_STAT *sbuf)
{
- return SMB_VFS_FILE_ID_CREATE(conn, sbuf->st_dev, sbuf->st_ino);
+ return SMB_VFS_FILE_ID_CREATE(conn, sbuf);
}
/*
@@ -49,7 +34,8 @@ struct file_id vfs_file_id_from_sbuf(connection_struct *conn, const SMB_STRUCT_S
*/
bool file_id_equal(const struct file_id *id1, const struct file_id *id2)
{
- return id1->inode == id2->inode && id1->devid == id2->devid;
+ return id1->inode == id2->inode && id1->devid == id2->devid &&
+ id1->extid == id2->extid;
}
/*
@@ -57,15 +43,17 @@ bool file_id_equal(const struct file_id *id1, const struct file_id *id2)
*/
const char *file_id_string_tos(const struct file_id *id)
{
- char *result = talloc_asprintf(talloc_tos(), "%llx:%llx",
+ char *result = talloc_asprintf(talloc_tos(), "%llx:%llx:%llx",
(unsigned long long)id->devid,
- (unsigned long long)id->inode);
+ (unsigned long long)id->inode,
+ (unsigned long long)id->extid);
SMB_ASSERT(result != NULL);
return result;
}
/*
- push a 16 byte version of a file id into a buffer
+ push a 16 byte version of a file id into a buffer. This ignores the extid
+ and is needed when dev/inodes are stored in persistent storage (tdbs).
*/
void push_file_id_16(char *buf, const struct file_id *id)
{
@@ -76,13 +64,28 @@ void push_file_id_16(char *buf, const struct file_id *id)
}
/*
- pul a 16 byte version of a file id from a buffer
+ push a 24 byte version of a file id into a buffer
+ */
+void push_file_id_24(char *buf, const struct file_id *id)
+{
+ SIVAL(buf, 0, id->devid&0xFFFFFFFF);
+ SIVAL(buf, 4, id->devid>>32);
+ SIVAL(buf, 8, id->inode&0xFFFFFFFF);
+ SIVAL(buf, 12, id->inode>>32);
+ SIVAL(buf, 16, id->extid&0xFFFFFFFF);
+ SIVAL(buf, 20, id->extid>>32);
+}
+
+/*
+ pull a 24 byte version of a file id from a buffer
*/
-void pull_file_id_16(char *buf, struct file_id *id)
+void pull_file_id_24(char *buf, struct file_id *id)
{
ZERO_STRUCTP(id);
id->devid = IVAL(buf, 0);
id->devid |= ((uint64_t)IVAL(buf,4))<<32;
id->inode = IVAL(buf, 8);
id->inode |= ((uint64_t)IVAL(buf,12))<<32;
+ id->extid = IVAL(buf, 16);
+ id->extid |= ((uint64_t)IVAL(buf,20))<<32;
}
diff --git a/source3/lib/ldap_debug_handler.c b/source3/lib/ldap_debug_handler.c
index 2181ff014d..98623d1985 100644
--- a/source3/lib/ldap_debug_handler.c
+++ b/source3/lib/ldap_debug_handler.c
@@ -19,13 +19,11 @@
#include "includes.h"
-#if HAVE_LDAP
-
+#if defined(HAVE_LDAP) && defined(HAVE_LBER_LOG_PRINT_FN)
static void samba_ldap_log_print_fn(LDAP_CONST char *data)
{
DEBUG(lp_ldap_debug_threshold(), ("[LDAP] %s", data));
}
-
#endif
void init_ldap_debugging(void)
diff --git a/source3/lib/secdesc.c b/source3/lib/secdesc.c
index 232bbca43c..a81c4ae82a 100644
--- a/source3/lib/secdesc.c
+++ b/source3/lib/secdesc.c
@@ -291,6 +291,32 @@ NTSTATUS marshall_sec_desc(TALLOC_CTX *mem_ctx,
}
/*******************************************************************
+ Convert a secdesc_buf into a byte stream
+********************************************************************/
+
+NTSTATUS marshall_sec_desc_buf(TALLOC_CTX *mem_ctx,
+ struct sec_desc_buf *secdesc_buf,
+ uint8_t **data, size_t *len)
+{
+ DATA_BLOB blob;
+ enum ndr_err_code ndr_err;
+
+ ndr_err = ndr_push_struct_blob(
+ &blob, mem_ctx, NULL, secdesc_buf,
+ (ndr_push_flags_fn_t)ndr_push_sec_desc_buf);
+
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(0, ("ndr_push_sec_desc_buf failed: %s\n",
+ ndr_errstr(ndr_err)));
+ return ndr_map_error2ntstatus(ndr_err);;
+ }
+
+ *data = blob.data;
+ *len = blob.length;
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
Parse a byte stream into a secdesc
********************************************************************/
NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len,
@@ -327,6 +353,43 @@ NTSTATUS unmarshall_sec_desc(TALLOC_CTX *mem_ctx, uint8 *data, size_t len,
}
/*******************************************************************
+ Parse a byte stream into a sec_desc_buf
+********************************************************************/
+
+NTSTATUS unmarshall_sec_desc_buf(TALLOC_CTX *mem_ctx, uint8_t *data, size_t len,
+ struct sec_desc_buf **psecdesc_buf)
+{
+ DATA_BLOB blob;
+ enum ndr_err_code ndr_err;
+ struct sec_desc_buf *result;
+
+ if ((data == NULL) || (len == 0)) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ result = TALLOC_ZERO_P(mem_ctx, struct sec_desc_buf);
+ if (result == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ blob = data_blob_const(data, len);
+
+ ndr_err = ndr_pull_struct_blob(
+ &blob, result, NULL, result,
+ (ndr_pull_flags_fn_t)ndr_pull_sec_desc_buf);
+
+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
+ DEBUG(0, ("ndr_pull_sec_desc_buf failed: %s\n",
+ ndr_errstr(ndr_err)));
+ TALLOC_FREE(result);
+ return ndr_map_error2ntstatus(ndr_err);;
+ }
+
+ *psecdesc_buf = result;
+ return NT_STATUS_OK;
+}
+
+/*******************************************************************
Creates a SEC_DESC structure with typical defaults.
********************************************************************/
diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c
index e36fa8a2a1..5a5c0ead65 100644
--- a/source3/lib/smbconf/smbconf_reg.c
+++ b/source3/lib/smbconf/smbconf_reg.c
@@ -23,7 +23,7 @@
#define INCLUDES_VALNAME "includes"
struct reg_private_data {
- NT_USER_TOKEN *token;
+ struct registry_key *base_key;
bool open; /* did _we_ open the registry? */
};
@@ -72,54 +72,6 @@ static bool smbconf_reg_valname_valid(const char *valname)
}
/**
- * Open a registry key specified by "path"
- */
-static WERROR smbconf_reg_open_path(TALLOC_CTX *mem_ctx,
- struct smbconf_ctx *ctx,
- const char *path,
- uint32 desired_access,
- struct registry_key **key)
-{
- WERROR werr = WERR_OK;
-
- if (ctx == NULL) {
- DEBUG(1, ("Error: configuration is not open!\n"));
- werr = WERR_INVALID_PARAM;
- goto done;
- }
-
- if (rpd(ctx)->token == NULL) {
- DEBUG(1, ("Error: token missing from smbconf_ctx. "
- "was smbconf_init() called?\n"));
- werr = WERR_INVALID_PARAM;
- goto done;
- }
-
- werr = ctx->ops->open_conf(ctx);
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(1, ("Error opening the registry.\n"));
- goto done;
- }
-
- if (path == NULL) {
- DEBUG(1, ("Error: NULL path string given\n"));
- werr = WERR_INVALID_PARAM;
- goto done;
- }
-
- werr = reg_open_path(mem_ctx, path, desired_access, rpd(ctx)->token,
- key);
-
- if (!W_ERROR_IS_OK(werr)) {
- DEBUG(5, ("Error opening registry path '%s': %s\n",
- path, win_errstr(werr)));
- }
-
-done:
- return werr;
-}
-
-/**
* Open a subkey of the base key (i.e a service)
*/
static WERROR smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx,
@@ -128,37 +80,12 @@ static WERROR smbconf_reg_open_service_key(TALLOC_CTX *mem_ctx,
uint32 desired_access,
struct registry_key **key)
{
- WERROR werr = WERR_OK;
- char *path = NULL;
-
if (servicename == NULL) {
- path = talloc_strdup(mem_ctx, ctx->path);
- } else {
- path = talloc_asprintf(mem_ctx, "%s\\%s", ctx->path,
- servicename);
- }
- if (path == NULL) {
- werr = WERR_NOMEM;
- goto done;
+ *key = rpd(ctx)->base_key;
+ return WERR_OK;
}
-
- werr = smbconf_reg_open_path(mem_ctx, ctx, path, desired_access, key);
-
-done:
- talloc_free(path);
- return werr;
-}
-
-/**
- * open the base key
- */
-static WERROR smbconf_reg_open_base_key(TALLOC_CTX *mem_ctx,
- struct smbconf_ctx *ctx,
- uint32 desired_access,
- struct registry_key **key)
-{
- return smbconf_reg_open_path(mem_ctx, ctx, ctx->path, desired_access,
- key);
+ return reg_openkey(mem_ctx, rpd(ctx)->base_key, servicename,
+ desired_access, key);
}
/**
@@ -189,7 +116,6 @@ static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx,
struct registry_key **newkey)
{
WERROR werr = WERR_OK;
- struct registry_key *create_parent = NULL;
TALLOC_CTX *create_ctx;
enum winreg_CreateAction action = REG_ACTION_NONE;
@@ -198,13 +124,7 @@ static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx,
* and will be destroyed when leaving this function... */
create_ctx = talloc_stackframe();
- werr = smbconf_reg_open_base_key(create_ctx, ctx, REG_KEY_WRITE,
- &create_parent);
- if (!W_ERROR_IS_OK(werr)) {
- goto done;
- }
-
- werr = reg_createkey(mem_ctx, create_parent, subkeyname,
+ werr = reg_createkey(mem_ctx, rpd(ctx)->base_key, subkeyname,
REG_KEY_WRITE, newkey, &action);
if (W_ERROR_IS_OK(werr) && (action != REG_CREATED_NEW_KEY)) {
DEBUG(10, ("Key '%s' already exists.\n", subkeyname));
@@ -215,7 +135,6 @@ static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx,
subkeyname, win_errstr(werr)));
}
-done:
talloc_free(create_ctx);
return werr;
}
@@ -608,6 +527,7 @@ done:
static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path)
{
WERROR werr = WERR_OK;
+ struct nt_user_token *token;
if (path == NULL) {
path = KEY_SMBCONF;
@@ -620,8 +540,7 @@ static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path)
ctx->data = TALLOC_ZERO_P(ctx, struct reg_private_data);
- werr = ntstatus_to_werror(registry_create_admin_token(ctx,
- &(rpd(ctx)->token)));
+ werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token));
if (!W_ERROR_IS_OK(werr)) {
DEBUG(1, ("Error creating admin token\n"));
goto done;
@@ -633,6 +552,19 @@ static WERROR smbconf_reg_init(struct smbconf_ctx *ctx, const char *path)
goto done;
}
+ werr = ctx->ops->open_conf(ctx);
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(1, ("Error opening the registry.\n"));
+ goto done;
+ }
+
+ werr = reg_open_path(ctx, ctx->path,
+ SEC_RIGHTS_ENUM_SUBKEYS | REG_KEY_WRITE,
+ token, &rpd(ctx)->base_key);
+ if (!W_ERROR_IS_OK(werr)) {
+ goto done;
+ }
+
done:
return werr;
}
@@ -723,6 +655,13 @@ static WERROR smbconf_reg_drop(struct smbconf_ctx *ctx)
struct registry_key *new_key = NULL;
TALLOC_CTX* mem_ctx = talloc_stackframe();
enum winreg_CreateAction action;
+ struct nt_user_token *token;
+
+ werr = ntstatus_to_werror(registry_create_admin_token(ctx, &token));
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(1, ("Error creating admin token\n"));
+ goto done;
+ }
path = talloc_strdup(mem_ctx, ctx->path);
if (path == NULL) {
@@ -731,8 +670,8 @@ static WERROR smbconf_reg_drop(struct smbconf_ctx *ctx)
}
p = strrchr(path, '\\');
*p = '\0';
- werr = smbconf_reg_open_path(mem_ctx, ctx, path, REG_KEY_WRITE,
- &parent_key);
+ werr = reg_open_path(mem_ctx, path, REG_KEY_WRITE, token,
+ &parent_key);
if (!W_ERROR_IS_OK(werr)) {
goto done;
@@ -765,7 +704,6 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx,
uint32_t added_count = 0;
TALLOC_CTX *tmp_ctx = NULL;
WERROR werr = WERR_OK;
- struct registry_key *key = NULL;
char *subkey_name = NULL;
char **tmp_share_names = NULL;
@@ -777,13 +715,8 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx,
tmp_ctx = talloc_stackframe();
/* if there are values in the base key, return NULL as share name */
- werr = smbconf_reg_open_base_key(tmp_ctx, ctx,
- SEC_RIGHTS_ENUM_SUBKEYS, &key);
- if (!W_ERROR_IS_OK(werr)) {
- goto done;
- }
- if (smbconf_reg_key_has_values(key)) {
+ if (smbconf_reg_key_has_values(rpd(ctx)->base_key)) {
werr = smbconf_add_string_to_array(tmp_ctx, &tmp_share_names,
0, NULL);
if (!W_ERROR_IS_OK(werr)) {
@@ -803,7 +736,8 @@ static WERROR smbconf_reg_get_share_names(struct smbconf_ctx *ctx,
}
for (count = 0;
- werr = reg_enumkey(tmp_ctx, key, count, &subkey_name, NULL),
+ werr = reg_enumkey(tmp_ctx, rpd(ctx)->base_key, count,
+ &subkey_name, NULL),
W_ERROR_IS_OK(werr);
count++)
{
@@ -865,18 +799,16 @@ static WERROR smbconf_reg_create_share(struct smbconf_ctx *ctx,
const char *servicename)
{
WERROR werr;
- TALLOC_CTX *mem_ctx = talloc_stackframe();
struct registry_key *key = NULL;
if (servicename == NULL) {
- werr = smbconf_reg_open_base_key(mem_ctx, ctx, REG_KEY_WRITE,
- &key);
- } else {
- werr = smbconf_reg_create_service_key(mem_ctx, ctx,
- servicename, &key);
+ return WERR_OK;
}
- talloc_free(mem_ctx);
+ werr = smbconf_reg_create_service_key(talloc_tos(), ctx,
+ servicename, &key);
+
+ talloc_free(key);
return werr;
}
@@ -896,6 +828,9 @@ static WERROR smbconf_reg_get_share(struct smbconf_ctx *ctx,
werr = smbconf_reg_open_service_key(tmp_ctx, ctx, servicename,
REG_KEY_READ, &key);
if (!W_ERROR_IS_OK(werr)) {
+ if (W_ERROR_EQUAL(werr, WERR_BADFILE)) {
+ werr = WERR_NO_SUCH_SERVICE;
+ }
goto done;
}
@@ -934,21 +869,15 @@ static WERROR smbconf_reg_delete_share(struct smbconf_ctx *ctx,
const char *servicename)
{
WERROR werr = WERR_OK;
- struct registry_key *key = NULL;
TALLOC_CTX *mem_ctx = talloc_stackframe();
- werr = smbconf_reg_open_base_key(mem_ctx, ctx, REG_KEY_WRITE, &key);
- if (!W_ERROR_IS_OK(werr)) {
- goto done;
- }
-
if (servicename != NULL) {
- werr = reg_deletekey_recursive(key, key, servicename);
+ werr = reg_deletekey_recursive(mem_ctx, rpd(ctx)->base_key,
+ servicename);
} else {
- werr = smbconf_reg_delete_values(key);
+ werr = smbconf_reg_delete_values(rpd(ctx)->base_key);
}
-done:
talloc_free(mem_ctx);
return werr;
}
@@ -1137,6 +1066,21 @@ done:
return werr;
}
+static WERROR smbconf_reg_transaction_start(struct smbconf_ctx *ctx)
+{
+ return regdb_transaction_start();
+}
+
+static WERROR smbconf_reg_transaction_commit(struct smbconf_ctx *ctx)
+{
+ return regdb_transaction_commit();
+}
+
+static WERROR smbconf_reg_transaction_cancel(struct smbconf_ctx *ctx)
+{
+ return regdb_transaction_cancel();
+}
+
struct smbconf_ops smbconf_ops_reg = {
.init = smbconf_reg_init,
.shutdown = smbconf_reg_shutdown,
@@ -1157,6 +1101,9 @@ struct smbconf_ops smbconf_ops_reg = {
.get_includes = smbconf_reg_get_includes,
.set_includes = smbconf_reg_set_includes,
.delete_includes = smbconf_reg_delete_includes,
+ .transaction_start = smbconf_reg_transaction_start,
+ .transaction_commit = smbconf_reg_transaction_commit,
+ .transaction_cancel = smbconf_reg_transaction_cancel,
};
diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c
index f0561a5081..e24d35818c 100644
--- a/source3/lib/smbldap.c
+++ b/source3/lib/smbldap.c
@@ -581,7 +581,9 @@ static void smbldap_store_state(LDAP *ld, struct smbldap_state *smbldap_state)
int smb_ldap_start_tls(LDAP *ldap_struct, int version)
{
+#ifdef LDAP_OPT_X_TLS
int rc;
+#endif
if (lp_ldap_ssl() != LDAP_SSL_START_TLS) {
return LDAP_SUCCESS;
diff --git a/source3/lib/system.c b/source3/lib/system.c
index ed66666ddb..10b55f662d 100644
--- a/source3/lib/system.c
+++ b/source3/lib/system.c
@@ -1043,35 +1043,6 @@ static char **extract_args(TALLOC_CTX *mem_ctx, const char *command)
}
/**************************************************************************
- Wrapper for fork. Ensures that mypid is reset. Used so we can write
- a sys_getpid() that only does a system call *once*.
-****************************************************************************/
-
-static pid_t mypid = (pid_t)-1;
-
-pid_t sys_fork(void)
-{
- pid_t forkret = fork();
-
- if (forkret == (pid_t)0) /* Child - reset mypid so sys_getpid does a system call. */
- mypid = (pid_t) -1;
-
- return forkret;
-}
-
-/**************************************************************************
- Wrapper for getpid. Ensures we only do a system call *once*.
-****************************************************************************/
-
-pid_t sys_getpid(void)
-{
- if (mypid == (pid_t)-1)
- mypid = getpid();
-
- return mypid;
-}
-
-/**************************************************************************
Wrapper for popen. Safer as it doesn't search a path.
Modified from the glibc sources.
modified by tridge to return a file descriptor. We must kick our FILE* habit
@@ -2008,7 +1979,6 @@ static ssize_t solaris_read_xattr(int attrfd, void *value, size_t size)
static ssize_t solaris_list_xattr(int attrdirfd, char *list, size_t size)
{
ssize_t len = 0;
- int stop = 0;
DIR *dirp;
struct dirent *de;
int newfd = dup(attrdirfd);
@@ -2080,7 +2050,7 @@ static int solaris_openat(int fildes, const char *path, int oflag, mode_t mode)
{
int filedes = openat(fildes, path, oflag, mode);
if (filedes == -1) {
- DEBUG(10,("openat FAILED: fd: %s, path: %s, errno: %s\n",filedes,path,strerror(errno)));
+ DEBUG(10,("openat FAILED: fd: %d, path: %s, errno: %s\n",filedes,path,strerror(errno)));
if (errno == EINVAL) {
errno = ENOTSUP;
} else {
diff --git a/source3/lib/tdb_validate.c b/source3/lib/tdb_validate.c
index 1f5dfe4d25..092546e3eb 100644
--- a/source3/lib/tdb_validate.c
+++ b/source3/lib/tdb_validate.c
@@ -118,7 +118,8 @@ int tdb_validate(struct tdb_context *tdb, tdb_validate_data_func validate_fn)
/* parent */
- DEBUG(10, ("tdb_validate: fork succeeded, child PID = %d\n",child_pid));
+ DEBUG(10, ("tdb_validate: fork succeeded, child PID = %u\n",
+ (unsigned int)child_pid));
DEBUG(10, ("tdb_validate: waiting for child to finish...\n"));
while ((wait_pid = sys_waitpid(child_pid, &child_status, 0)) < 0) {
@@ -134,7 +135,7 @@ int tdb_validate(struct tdb_context *tdb, tdb_validate_data_func validate_fn)
}
if (wait_pid != child_pid) {
DEBUG(1, ("tdb_validate: waitpid returned pid %d, "
- "but %d was expected\n", wait_pid, child_pid));
+ "but %u was expected\n", wait_pid, (unsigned int)child_pid));
goto done;
}
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 6079e71063..89f7be8e6c 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -798,43 +798,6 @@ char *clean_name(TALLOC_CTX *ctx, const char *s)
}
/*******************************************************************
- Close the low 3 fd's and open dev/null in their place.
-********************************************************************/
-
-void close_low_fds(bool stderr_too)
-{
-#ifndef VALGRIND
- int fd;
- int i;
-
- close(0);
- close(1);
-
- if (stderr_too)
- close(2);
-
- /* try and use up these file descriptors, so silly
- library routines writing to stdout etc won't cause havoc */
- for (i=0;i<3;i++) {
- if (i == 2 && !stderr_too)
- continue;
-
- fd = sys_open("/dev/null",O_RDWR,0);
- if (fd < 0)
- fd = sys_open("/dev/null",O_WRONLY,0);
- if (fd < 0) {
- DEBUG(0,("Can't open /dev/null\n"));
- return;
- }
- if (fd != i) {
- DEBUG(0,("Didn't get file descriptor %d\n",i));
- return;
- }
- }
-#endif
-}
-
-/*******************************************************************
Write data into an fd at a given offset. Ignore seek errors.
********************************************************************/
@@ -924,36 +887,6 @@ void smb_msleep(unsigned int t)
#endif
}
-/****************************************************************************
- Become a daemon, discarding the controlling terminal.
-****************************************************************************/
-
-void become_daemon(bool Fork, bool no_process_group)
-{
- if (Fork) {
- if (sys_fork()) {
- _exit(0);
- }
- }
-
- /* detach from the terminal */
-#ifdef HAVE_SETSID
- if (!no_process_group) setsid();
-#elif defined(TIOCNOTTY)
- if (!no_process_group) {
- int i = sys_open("/dev/tty", O_RDWR, 0);
- if (i != -1) {
- ioctl(i, (int) TIOCNOTTY, (char *)0);
- close(i);
- }
- }
-#endif /* HAVE_SETSID */
-
- /* Close fd's 0,1,2. Needed if started by rsh */
- close_low_fds(False); /* Don't close stderr, let the debug system
- attach it to the logfile */
-}
-
bool reinit_after_fork(struct messaging_context *msg_ctx,
struct event_context *ev_ctx,
bool parent_longlived)
@@ -966,6 +899,13 @@ bool reinit_after_fork(struct messaging_context *msg_ctx,
* numbers as each other */
set_need_random_reseed();
+#ifdef WITH_MADVISE_PROTECTED
+ /* Protect parent process from being killed by kernel when system
+ * memory is low. Child processes can still be killed */
+ if(!parent_longlived)
+ madvise(NULL,0,MADV_PROTECT);
+#endif
+
/* tdb needs special fork handling */
if (tdb_reopen_all(parent_longlived ? 1 : 0) == -1) {
DEBUG(0,("tdb_reopen_all failed.\n"));
@@ -3205,102 +3145,3 @@ const char *strip_hostname(const char *s)
return s;
}
-
-struct read_pkt_state {
- struct event_context *ev;
- int fd;
- uint8_t *buf;
- ssize_t (*more)(uint8_t *buf, size_t buflen, void *priv);
- void *priv;
-};
-
-static void read_pkt_done(struct async_req *subreq);
-
-struct async_req *read_pkt_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- int fd, size_t initial,
- ssize_t (*more)(uint8_t *buf, size_t buflen,
- void *priv),
- void *priv)
-{
- struct async_req *result, *subreq;
- struct read_pkt_state *state;
-
- if (!async_req_setup(mem_ctx, &result, &state,
- struct read_pkt_state)) {
- return NULL;
- }
- state->ev = ev;
- state->fd = fd;
- state->more = more;
-
- state->buf = talloc_array(state, uint8_t, initial);
- if (state->buf == NULL) {
- goto fail;
- }
- subreq = recvall_send(state, ev, fd, state->buf, initial, 0);
- if (subreq == NULL) {
- goto fail;
- }
- subreq->async.fn = read_pkt_done;
- subreq->async.priv = result;
- return result;
- fail:
- TALLOC_FREE(result);
- return NULL;
-}
-
-static void read_pkt_done(struct async_req *subreq)
-{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct read_pkt_state *state = talloc_get_type_abort(
- req->private_data, struct read_pkt_state);
- size_t current_size;
- ssize_t received;
- ssize_t more;
- int err;
-
- received = recvall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (received == -1) {
- async_req_error(req, err);
- return;
- }
- current_size = talloc_get_size(state->buf);
-
- more = state->more(state->buf, current_size, state->priv);
- if (more < 0) {
- async_req_error(req, EIO);
- return;
- }
- if (more == 0) {
- async_req_done(req);
- return;
- }
- state->buf = TALLOC_REALLOC_ARRAY(state, state->buf, uint8_t,
- current_size + more);
- if (async_req_nomem(state->buf, req)) {
- return;
- }
- subreq = recvall_send(state, state->ev, state->fd,
- state->buf + current_size, more, 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
- subreq->async.fn = read_pkt_done;
- subreq->async.priv = req;
-}
-
-ssize_t read_pkt_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
- uint8_t **pbuf, int *perr)
-{
- struct read_pkt_state *state = talloc_get_type_abort(
- req->private_data, struct read_pkt_state);
-
- if (async_req_is_errno(req, perr)) {
- return -1;
- }
- *pbuf = talloc_move(mem_ctx, &state->buf);
- return talloc_get_size(*pbuf);
-}
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index c46aa2ac49..6e75a67a85 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -953,7 +953,7 @@ struct open_socket_out_state {
int wait_nsec;
};
-static void open_socket_out_connected(struct async_req *subreq);
+static void open_socket_out_connected(struct tevent_req *subreq);
static int open_socket_out_state_destructor(struct open_socket_out_state *s)
{
@@ -967,19 +967,20 @@ static int open_socket_out_state_destructor(struct open_socket_out_state *s)
Create an outgoing socket. timeout is in milliseconds.
**************************************************************************/
-struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
- const struct sockaddr_storage *pss,
- uint16_t port,
- int timeout)
+struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
+ struct event_context *ev,
+ const struct sockaddr_storage *pss,
+ uint16_t port,
+ int timeout)
{
char addr[INET6_ADDRSTRLEN];
- struct async_req *result, *subreq;
+ struct tevent_req *result, *subreq;
struct open_socket_out_state *state;
NTSTATUS status;
- if (!async_req_setup(mem_ctx, &result, &state,
- struct open_socket_out_state)) {
+ result = tevent_req_create(mem_ctx, &state,
+ struct open_socket_out_state);
+ if (result == NULL) {
return NULL;
}
state->ev = ev;
@@ -995,7 +996,8 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
}
talloc_set_destructor(state, open_socket_out_state_destructor);
- if (!async_req_set_timeout(result, ev, timeval_set(0, timeout*1000))) {
+ if (!tevent_req_set_endtime(
+ result, ev, timeval_current_ofs(0, timeout*1000))) {
goto fail;
}
@@ -1026,38 +1028,36 @@ struct async_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
(struct sockaddr *)&state->ss,
state->salen);
if ((subreq == NULL)
- || !async_req_set_timeout(subreq, state->ev,
- timeval_set(0, state->wait_nsec))) {
- status = NT_STATUS_NO_MEMORY;
- goto post_status;
+ || !tevent_req_set_endtime(
+ subreq, state->ev,
+ timeval_current_ofs(0, state->wait_nsec))) {
+ goto fail;
}
subreq->async.fn = open_socket_out_connected;
- subreq->async.priv = result;
+ subreq->async.private_data = result;
return result;
post_status:
- if (!async_post_ntstatus(result, ev, status)) {
- goto fail;
- }
- return result;
+ tevent_req_nterror(result, status);
+ return tevent_req_post(result, ev);
fail:
TALLOC_FREE(result);
return NULL;
}
-static void open_socket_out_connected(struct async_req *subreq)
+static void open_socket_out_connected(struct tevent_req *subreq)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ struct tevent_req *req = talloc_get_type_abort(
+ subreq->async.private_data, struct tevent_req);
struct open_socket_out_state *state = talloc_get_type_abort(
- req->private_data, struct open_socket_out_state);
- int err;
+ req->private_state, struct open_socket_out_state);
+ int ret;
int sys_errno;
- err = async_connect_recv(subreq, &sys_errno);
+ ret = async_connect_recv(subreq, &sys_errno);
TALLOC_FREE(subreq);
- if (err == 0) {
- async_req_done(req);
+ if (ret == 0) {
+ tevent_req_done(req);
return;
}
@@ -1080,38 +1080,39 @@ static void open_socket_out_connected(struct async_req *subreq)
subreq = async_connect_send(state, state->ev, state->fd,
(struct sockaddr *)&state->ss,
state->salen);
- if (async_req_nomem(subreq, req)) {
+ if (tevent_req_nomem(subreq, req)) {
return;
}
- if (!async_req_set_timeout(subreq, state->ev,
- timeval_set(0, state->wait_nsec))) {
- async_req_error(req, ENOMEM);
+ if (!tevent_req_set_endtime(
+ subreq, state->ev,
+ timeval_current_ofs(0, state->wait_nsec))) {
+ tevent_req_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
subreq->async.fn = open_socket_out_connected;
- subreq->async.priv = req;
+ subreq->async.private_data = req;
return;
}
#ifdef EISCONN
if (sys_errno == EISCONN) {
- async_req_done(req);
+ tevent_req_done(req);
return;
}
#endif
/* real error */
- async_req_error(req, sys_errno);
+ tevent_req_nterror(req, map_nt_error_from_unix(sys_errno));
}
-NTSTATUS open_socket_out_recv(struct async_req *req, int *pfd)
+NTSTATUS open_socket_out_recv(struct tevent_req *req, int *pfd)
{
struct open_socket_out_state *state = talloc_get_type_abort(
- req->private_data, struct open_socket_out_state);
- int err;
+ req->private_state, struct open_socket_out_state);
+ NTSTATUS status;
- if (async_req_is_errno(req, &err)) {
- return map_nt_error_from_unix(err);
+ if (tevent_req_is_nterror(req, &status)) {
+ return status;
}
*pfd = state->fd;
state->fd = -1;
@@ -1123,7 +1124,7 @@ NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
{
TALLOC_CTX *frame = talloc_stackframe();
struct event_context *ev;
- struct async_req *req;
+ struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
ev = event_context_init(frame);
@@ -1135,10 +1136,10 @@ NTSTATUS open_socket_out(const struct sockaddr_storage *pss, uint16_t port,
if (req == NULL) {
goto fail;
}
- while (req->state < ASYNC_REQ_DONE) {
- event_loop_once(ev);
+ if (!tevent_req_poll(req, ev)) {
+ status = NT_STATUS_INTERNAL_ERROR;
+ goto fail;
}
-
status = open_socket_out_recv(req, pfd);
fail:
TALLOC_FREE(frame);
@@ -1154,7 +1155,7 @@ struct open_socket_out_defer_state {
};
static void open_socket_out_defer_waited(struct async_req *subreq);
-static void open_socket_out_defer_connected(struct async_req *subreq);
+static void open_socket_out_defer_connected(struct tevent_req *subreq);
struct async_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
struct event_context *ev,
@@ -1201,6 +1202,7 @@ static void open_socket_out_defer_waited(struct async_req *subreq)
subreq->async.priv, struct async_req);
struct open_socket_out_defer_state *state = talloc_get_type_abort(
req->private_data, struct open_socket_out_defer_state);
+ struct tevent_req *subreq2;
bool ret;
ret = async_wait_recv(subreq);
@@ -1210,19 +1212,19 @@ static void open_socket_out_defer_waited(struct async_req *subreq)
return;
}
- subreq = open_socket_out_send(state, state->ev, &state->ss,
- state->port, state->timeout);
- if (async_req_nomem(subreq, req)) {
+ subreq2 = open_socket_out_send(state, state->ev, &state->ss,
+ state->port, state->timeout);
+ if (async_req_nomem(subreq2, req)) {
return;
}
- subreq->async.fn = open_socket_out_defer_connected;
- subreq->async.priv = req;
+ subreq2->async.fn = open_socket_out_defer_connected;
+ subreq2->async.private_data = req;
}
-static void open_socket_out_defer_connected(struct async_req *subreq)
+static void open_socket_out_defer_connected(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ subreq->async.private_data, struct async_req);
struct open_socket_out_defer_state *state = talloc_get_type_abort(
req->private_data, struct open_socket_out_defer_state);
NTSTATUS status;
diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c
index 9358061797..b9ccb83e55 100644
--- a/source3/lib/util_str.c
+++ b/source3/lib/util_str.c
@@ -36,118 +36,6 @@ const char toupper_ascii_fast_table[128] = {
};
/**
- * @file
- * @brief String utilities.
- **/
-
-static bool next_token_internal_talloc(TALLOC_CTX *ctx,
- const char **ptr,
- char **pp_buff,
- const char *sep,
- bool ltrim)
-{
- char *s;
- char *saved_s;
- char *pbuf;
- bool quoted;
- size_t len=1;
-
- *pp_buff = NULL;
- if (!ptr) {
- return(false);
- }
-
- s = (char *)*ptr;
-
- /* default to simple separators */
- if (!sep) {
- sep = " \t\n\r";
- }
-
- /* find the first non sep char, if left-trimming is requested */
- if (ltrim) {
- while (*s && strchr_m(sep,*s)) {
- s++;
- }
- }
-
- /* nothing left? */
- if (!*s) {
- return false;
- }
-
- /* When restarting we need to go from here. */
- saved_s = s;
-
- /* Work out the length needed. */
- for (quoted = false; *s &&
- (quoted || !strchr_m(sep,*s)); s++) {
- if (*s == '\"') {
- quoted = !quoted;
- } else {
- len++;
- }
- }
-
- /* We started with len = 1 so we have space for the nul. */
- *pp_buff = TALLOC_ARRAY(ctx, char, len);
- if (!*pp_buff) {
- return false;
- }
-
- /* copy over the token */
- pbuf = *pp_buff;
- s = saved_s;
- for (quoted = false; *s &&
- (quoted || !strchr_m(sep,*s)); s++) {
- if ( *s == '\"' ) {
- quoted = !quoted;
- } else {
- *pbuf++ = *s;
- }
- }
-
- *ptr = (*s) ? s+1 : s;
- *pbuf = 0;
-
- return true;
-}
-
-#if 0
-/*
- * Get the next token from a string, return false if none found. Handles
- * double-quotes. This version trims leading separator characters before
- * looking for a token.
- */
-bool next_token(const char **ptr, char *buff, const char *sep, size_t bufsize)
-{
- return next_token_internal(ptr, buff, sep, bufsize, true);
-}
-#endif
-
-bool next_token_talloc(TALLOC_CTX *ctx,
- const char **ptr,
- char **pp_buff,
- const char *sep)
-{
- return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true);
-}
-
-/*
- * Get the next token from a string, return false if none found. Handles
- * double-quotes. This version does not trim leading separator characters
- * before looking for a token.
- */
-
-bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx,
- const char **ptr,
- char **pp_buff,
- const char *sep)
-{
- return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false);
-}
-
-/**
* Case insensitive string compararison.
*
* iconv does not directly give us a way to compare strings in
diff --git a/source3/lib/wb_reqtrans.c b/source3/lib/wb_reqtrans.c
index 9bf6f29105..65906dcb91 100644
--- a/source3/lib/wb_reqtrans.c
+++ b/source3/lib/wb_reqtrans.c
@@ -27,9 +27,7 @@
struct req_read_state {
struct winbindd_request *wb_req;
- struct tevent_context *ev;
size_t max_extra_data;
- int fd;
};
bool async_req_is_wbcerr(struct async_req *req, wbcErr *pwbc_err)
@@ -83,145 +81,91 @@ wbcErr async_req_simple_recv_wbcerr(struct async_req *req)
return WBC_ERR_SUCCESS;
}
-static void wb_req_read_len(struct async_req *subreq);
-static void wb_req_read_main(struct async_req *subreq);
-static void wb_req_read_extra(struct async_req *subreq);
+static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data);
+static void wb_req_read_done(struct tevent_req *subreq);
struct async_req *wb_req_read_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
int fd, size_t max_extra_data)
{
- struct async_req *result, *subreq;
+ struct async_req *result;
+ struct tevent_req *subreq;
struct req_read_state *state;
if (!async_req_setup(mem_ctx, &result, &state,
struct req_read_state)) {
return NULL;
}
- state->fd = fd;
- state->ev = ev;
state->max_extra_data = max_extra_data;
- state->wb_req = talloc(state, struct winbindd_request);
- if (state->wb_req == NULL) {
- goto nomem;
- }
- subreq = recvall_send(state, ev, state->fd, &(state->wb_req->length),
- sizeof(state->wb_req->length), 0);
+ subreq = read_packet_send(state, ev, fd, 4, wb_req_more, state);
if (subreq == NULL) {
goto nomem;
}
- subreq->async.fn = wb_req_read_len;
- subreq->async.priv = result;
+ subreq->async.fn = wb_req_read_done;
+ subreq->async.private_data = result;
return result;
-
nomem:
TALLOC_FREE(result);
return NULL;
}
-static void wb_req_read_len(struct async_req *subreq)
+static ssize_t wb_req_more(uint8_t *buf, size_t buflen, void *private_data)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
struct req_read_state *state = talloc_get_type_abort(
- req->private_data, struct req_read_state);
- int err;
- ssize_t ret;
-
- ret = recvall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (ret < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
+ private_data, struct req_read_state);
+ struct winbindd_request *req = (struct winbindd_request *)buf;
- if (state->wb_req->length != sizeof(struct winbindd_request)) {
- DEBUG(0, ("wb_req_read_len: Invalid request size received: "
- "%d (expected %d)\n", (int)state->wb_req->length,
- (int)sizeof(struct winbindd_request)));
- async_req_error(req, WBC_ERR_INVALID_RESPONSE);
- return;
+ if (buflen == 4) {
+ if (req->length != sizeof(struct winbindd_request)) {
+ DEBUG(0, ("wb_req_read_len: Invalid request size "
+ "received: %d (expected %d)\n",
+ (int)req->length,
+ (int)sizeof(struct winbindd_request)));
+ return -1;
+ }
+ return sizeof(struct winbindd_request) - 4;
}
- subreq = recvall_send(
- req, state->ev, state->fd, (uint32 *)(state->wb_req)+1,
- sizeof(struct winbindd_request) - sizeof(uint32), 0);
- if (async_req_nomem(subreq, req)) {
- return;
+ if ((state->max_extra_data != 0)
+ && (req->extra_len > state->max_extra_data)) {
+ DEBUG(3, ("Got request with %d bytes extra data on "
+ "unprivileged socket\n", (int)req->extra_len));
+ return -1;
}
- subreq->async.fn = wb_req_read_main;
- subreq->async.priv = req;
+ return req->extra_len;
}
-static void wb_req_read_main(struct async_req *subreq)
+static void wb_req_read_done(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ subreq->async.private_data, struct async_req);
struct req_read_state *state = talloc_get_type_abort(
req->private_data, struct req_read_state);
int err;
ssize_t ret;
+ uint8_t *buf;
- ret = recvall_recv(subreq, &err);
+ ret = read_packet_recv(subreq, state, &buf, &err);
TALLOC_FREE(subreq);
- if (ret < 0) {
+ if (ret == -1) {
async_req_error(req, map_wbc_err_from_errno(err));
return;
}
- if ((state->max_extra_data != 0)
- && (state->wb_req->extra_len > state->max_extra_data)) {
- DEBUG(3, ("Got request with %d bytes extra data on "
- "unprivileged socket\n",
- (int)state->wb_req->extra_len));
- async_req_error(req, WBC_ERR_INVALID_RESPONSE);
- return;
- }
-
- if (state->wb_req->extra_len == 0) {
- async_req_done(req);
- return;
- }
-
- state->wb_req->extra_data.data = TALLOC_ARRAY(
- state->wb_req, char, state->wb_req->extra_len + 1);
- if (async_req_nomem(state->wb_req->extra_data.data, req)) {
- return;
- }
-
- state->wb_req->extra_data.data[state->wb_req->extra_len] = 0;
-
- subreq = recvall_send(
- req, state->ev, state->fd, state->wb_req->extra_data.data,
- state->wb_req->extra_len, 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
-
- subreq->async.fn = wb_req_read_extra;
- subreq->async.priv = req;
-}
-
-static void wb_req_read_extra(struct async_req *subreq)
-{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- int err;
- ssize_t ret;
+ state->wb_req = (struct winbindd_request *)buf;
- ret = recvall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (ret < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
+ if (state->wb_req->extra_len != 0) {
+ state->wb_req->extra_data.data =
+ (char *)buf + sizeof(struct winbindd_request);
+ } else {
+ state->wb_req->extra_data.data = NULL;
}
async_req_done(req);
}
-
wbcErr wb_req_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
struct winbindd_request **preq)
{
@@ -237,90 +181,60 @@ wbcErr wb_req_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
}
struct req_write_state {
- struct winbindd_request *wb_req;
- struct tevent_context *ev;
- int fd;
+ struct iovec iov[2];
};
-static void wb_req_write_main(struct async_req *subreq);
-static void wb_req_write_extra(struct async_req *subreq);
+static void wb_req_write_done(struct tevent_req *subreq);
struct async_req *wb_req_write_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev, int fd,
struct winbindd_request *wb_req)
{
- struct async_req *result, *subreq;
+ struct async_req *result;
+ struct tevent_req *subreq;
struct req_write_state *state;
+ int count = 1;
if (!async_req_setup(mem_ctx, &result, &state,
struct req_write_state)) {
return NULL;
}
- state->fd = fd;
- state->ev = ev;
- state->wb_req = wb_req;
- subreq = sendall_send(state, state->ev, state->fd, state->wb_req,
- sizeof(struct winbindd_request), 0);
- if (subreq == NULL) {
- goto nomem;
+ state->iov[0].iov_base = wb_req;
+ state->iov[0].iov_len = sizeof(struct winbindd_request);
+
+ if (wb_req->extra_len != 0) {
+ state->iov[1].iov_base = wb_req->extra_data.data;
+ state->iov[1].iov_len = wb_req->extra_len;
+ count = 2;
}
- subreq->async.fn = wb_req_write_main;
- subreq->async.priv = result;
+ subreq = writev_send(state, ev, fd, state->iov, count);
+ if (subreq == NULL) {
+ goto fail;
+ }
+ subreq->async.fn = wb_req_write_done;
+ subreq->async.private_data = result;
return result;
- nomem:
+ fail:
TALLOC_FREE(result);
return NULL;
}
-static void wb_req_write_main(struct async_req *subreq)
-{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct req_write_state *state = talloc_get_type_abort(
- req->private_data, struct req_write_state);
- int err;
- ssize_t ret;
-
- ret = sendall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (ret < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
-
- if (state->wb_req->extra_len == 0) {
- async_req_done(req);
- return;
- }
-
- subreq = sendall_send(state, state->ev, state->fd,
- state->wb_req->extra_data.data,
- state->wb_req->extra_len, 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
-
- subreq->async.fn = wb_req_write_extra;
- subreq->async.priv = req;
-}
-
-static void wb_req_write_extra(struct async_req *subreq)
+static void wb_req_write_done(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ subreq->async.private_data, struct async_req);
int err;
ssize_t ret;
- ret = sendall_recv(subreq, &err);
+ ret = writev_recv(subreq, &err);
TALLOC_FREE(subreq);
if (ret < 0) {
async_req_error(req, map_wbc_err_from_errno(err));
return;
}
-
async_req_done(req);
}
@@ -331,40 +245,29 @@ wbcErr wb_req_write_recv(struct async_req *req)
struct resp_read_state {
struct winbindd_response *wb_resp;
- struct tevent_context *ev;
- size_t max_extra_data;
- int fd;
};
-static void wb_resp_read_len(struct async_req *subreq);
-static void wb_resp_read_main(struct async_req *subreq);
-static void wb_resp_read_extra(struct async_req *subreq);
+static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data);
+static void wb_resp_read_done(struct tevent_req *subreq);
struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev, int fd)
{
- struct async_req *result, *subreq;
+ struct async_req *result;
+ struct tevent_req *subreq;
struct resp_read_state *state;
if (!async_req_setup(mem_ctx, &result, &state,
struct resp_read_state)) {
return NULL;
}
- state->fd = fd;
- state->ev = ev;
- state->wb_resp = talloc(state, struct winbindd_response);
- if (state->wb_resp == NULL) {
- goto nomem;
- }
- subreq = recvall_send(state, ev, state->fd, &(state->wb_resp->length),
- sizeof(state->wb_resp->length), 0);
+ subreq = read_packet_send(state, ev, fd, 4, wb_resp_more, state);
if (subreq == NULL) {
goto nomem;
}
-
- subreq->async.fn = wb_resp_read_len;
- subreq->async.priv = result;
+ subreq->async.fn = wb_resp_read_done;
+ subreq->async.private_data = result;
return result;
nomem:
@@ -372,100 +275,50 @@ struct async_req *wb_resp_read_send(TALLOC_CTX *mem_ctx,
return NULL;
}
-static void wb_resp_read_len(struct async_req *subreq)
+static ssize_t wb_resp_more(uint8_t *buf, size_t buflen, void *private_data)
{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct resp_read_state *state = talloc_get_type_abort(
- req->private_data, struct resp_read_state);
- int err;
- ssize_t ret;
-
- ret = recvall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (ret < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
-
- if (state->wb_resp->length < sizeof(struct winbindd_response)) {
- DEBUG(0, ("wb_resp_read_len: Invalid response size received: "
- "%d (expected at least%d)\n",
- (int)state->wb_resp->length,
- (int)sizeof(struct winbindd_response)));
- async_req_error(req, WBC_ERR_INVALID_RESPONSE);
- return;
- }
-
- subreq = recvall_send(
- req, state->ev, state->fd, (uint32 *)(state->wb_resp)+1,
- sizeof(struct winbindd_response) - sizeof(uint32), 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
-
- subreq->async.fn = wb_resp_read_main;
- subreq->async.priv = req;
+ struct winbindd_response *resp = (struct winbindd_response *)buf;
+
+ if (buflen == 4) {
+ if (resp->length < sizeof(struct winbindd_response)) {
+ DEBUG(0, ("wb_resp_read_len: Invalid response size "
+ "received: %d (expected at least%d)\n",
+ (int)resp->length,
+ (int)sizeof(struct winbindd_response)));
+ return -1;
+ }
+ }
+ return resp->length - buflen;
}
-static void wb_resp_read_main(struct async_req *subreq)
+static void wb_resp_read_done(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
+ subreq->async.private_data, struct async_req);
struct resp_read_state *state = talloc_get_type_abort(
req->private_data, struct resp_read_state);
+ uint8_t *buf;
int err;
ssize_t ret;
- size_t extra_len;
- ret = recvall_recv(subreq, &err);
+ ret = read_packet_recv(subreq, state, &buf, &err);
TALLOC_FREE(subreq);
- if (ret < 0) {
+ if (ret == -1) {
async_req_error(req, map_wbc_err_from_errno(err));
return;
}
- extra_len = state->wb_resp->length - sizeof(struct winbindd_response);
- if (extra_len == 0) {
- async_req_done(req);
- return;
- }
-
- state->wb_resp->extra_data.data = TALLOC_ARRAY(
- state->wb_resp, char, extra_len+1);
- if (async_req_nomem(state->wb_resp->extra_data.data, req)) {
- return;
- }
- ((char *)state->wb_resp->extra_data.data)[extra_len] = 0;
-
- subreq = recvall_send(
- req, state->ev, state->fd, state->wb_resp->extra_data.data,
- extra_len, 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
-
- subreq->async.fn = wb_resp_read_extra;
- subreq->async.priv = req;
-}
-
-static void wb_resp_read_extra(struct async_req *subreq)
-{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- int err;
- ssize_t ret;
+ state->wb_resp = (struct winbindd_response *)buf;
- ret = recvall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (ret < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
+ if (state->wb_resp->length > sizeof(struct winbindd_response)) {
+ state->wb_resp->extra_data.data =
+ (char *)buf + sizeof(struct winbindd_response);
+ } else {
+ state->wb_resp->extra_data.data = NULL;
}
async_req_done(req);
}
-
wbcErr wb_resp_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
struct winbindd_response **presp)
{
@@ -481,91 +334,61 @@ wbcErr wb_resp_read_recv(struct async_req *req, TALLOC_CTX *mem_ctx,
}
struct resp_write_state {
- struct winbindd_response *wb_resp;
- struct tevent_context *ev;
- int fd;
+ struct iovec iov[2];
};
-static void wb_resp_write_main(struct async_req *subreq);
-static void wb_resp_write_extra(struct async_req *subreq);
+static void wb_resp_write_done(struct tevent_req *subreq);
struct async_req *wb_resp_write_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev, int fd,
struct winbindd_response *wb_resp)
{
- struct async_req *result, *subreq;
+ struct async_req *result;
+ struct tevent_req *subreq;
struct resp_write_state *state;
+ int count = 1;
if (!async_req_setup(mem_ctx, &result, &state,
struct resp_write_state)) {
return NULL;
}
- state->fd = fd;
- state->ev = ev;
- state->wb_resp = wb_resp;
- subreq = sendall_send(state, state->ev, state->fd, state->wb_resp,
- sizeof(struct winbindd_response), 0);
- if (subreq == NULL) {
- goto nomem;
+ state->iov[0].iov_base = wb_resp;
+ state->iov[0].iov_len = sizeof(struct winbindd_response);
+
+ if (wb_resp->length > sizeof(struct winbindd_response)) {
+ state->iov[1].iov_base = wb_resp->extra_data.data;
+ state->iov[1].iov_len =
+ wb_resp->length - sizeof(struct winbindd_response);
+ count = 2;
}
- subreq->async.fn = wb_resp_write_main;
- subreq->async.priv = result;
+ subreq = writev_send(state, ev, fd, state->iov, count);
+ if (subreq == NULL) {
+ goto fail;
+ }
+ subreq->async.fn = wb_resp_write_done;
+ subreq->async.private_data = result;
return result;
- nomem:
+ fail:
TALLOC_FREE(result);
return NULL;
}
-static void wb_resp_write_main(struct async_req *subreq)
+static void wb_resp_write_done(struct tevent_req *subreq)
{
struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- struct resp_write_state *state = talloc_get_type_abort(
- req->private_data, struct resp_write_state);
+ subreq->async.private_data, struct async_req);
int err;
ssize_t ret;
- ret = sendall_recv(subreq, &err);
+ ret = writev_recv(subreq, &err);
TALLOC_FREE(subreq);
if (ret < 0) {
async_req_error(req, map_wbc_err_from_errno(err));
return;
}
-
- if (state->wb_resp->length == sizeof(struct winbindd_response)) {
- async_req_done(req);
- return;
- }
-
- subreq = sendall_send(
- state, state->ev, state->fd,
- state->wb_resp->extra_data.data,
- state->wb_resp->length - sizeof(struct winbindd_response), 0);
- if (async_req_nomem(subreq, req)) {
- return;
- }
-
- subreq->async.fn = wb_resp_write_extra;
- subreq->async.priv = req;
-}
-
-static void wb_resp_write_extra(struct async_req *subreq)
-{
- struct async_req *req = talloc_get_type_abort(
- subreq->async.priv, struct async_req);
- int err;
- ssize_t ret;
-
- ret = sendall_recv(subreq, &err);
- TALLOC_FREE(subreq);
- if (err < 0) {
- async_req_error(req, map_wbc_err_from_errno(err));
- return;
- }
-
async_req_done(req);
}
diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c
index 4d3a609530..b8d55a944a 100644
--- a/source3/lib/wbclient.c
+++ b/source3/lib/wbclient.c
@@ -147,17 +147,30 @@ struct wb_context *wb_context_init(TALLOC_CTX *mem_ctx)
return result;
}
+struct wb_connect_state {
+ int dummy;
+};
+
+static void wbc_connect_connected(struct tevent_req *subreq);
+
static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx,
- struct tevent_context *ev,
- struct wb_context *wb_ctx,
- const char *dir)
+ struct tevent_context *ev,
+ struct wb_context *wb_ctx,
+ const char *dir)
{
- struct async_req *req;
+ struct async_req *result;
+ struct tevent_req *subreq;
+ struct wb_connect_state *state;
struct sockaddr_un sunaddr;
struct stat st;
char *path = NULL;
wbcErr wbc_err;
+ if (!async_req_setup(mem_ctx, &result, &state,
+ struct wb_connect_state)) {
+ return NULL;
+ }
+
if (wb_ctx->fd != -1) {
close(wb_ctx->fd);
wb_ctx->fd = -1;
@@ -205,33 +218,46 @@ static struct async_req *wb_connect_send(TALLOC_CTX *mem_ctx,
goto post_status;
}
- req = async_connect_send(mem_ctx, ev, wb_ctx->fd,
- (struct sockaddr *)&sunaddr,
- sizeof(sunaddr));
- if (req == NULL) {
+ subreq = async_connect_send(mem_ctx, ev, wb_ctx->fd,
+ (struct sockaddr *)&sunaddr,
+ sizeof(sunaddr));
+ if (subreq == NULL) {
goto nomem;
}
- if (!async_req_set_timeout(req, ev, timeval_set(30, 0))) {
- TALLOC_FREE(req);
+ subreq->async.fn = wbc_connect_connected;
+ subreq->async.private_data = result;
+
+ if (!tevent_req_set_endtime(subreq, ev, timeval_current_ofs(30, 0))) {
goto nomem;
}
- return req;
+ return result;
nomem:
wbc_err = WBC_ERR_NO_MEMORY;
post_status:
- req = async_req_new(mem_ctx);
- if (req == NULL) {
- return NULL;
- }
- if (async_post_error(req, ev, wbc_err)) {
- return req;
+ if (async_post_error(result, ev, wbc_err)) {
+ return result;
}
- TALLOC_FREE(req);
+ TALLOC_FREE(result);
return NULL;
}
+static void wbc_connect_connected(struct tevent_req *subreq)
+{
+ struct async_req *req = talloc_get_type_abort(
+ subreq->async.private_data, struct async_req);
+ int res, err;
+
+ res = async_connect_recv(subreq, &err);
+ TALLOC_FREE(subreq);
+ if (res == -1) {
+ async_req_error(req, map_wbc_err_from_errno(err));
+ return;
+ }
+ async_req_done(req);
+}
+
static wbcErr wb_connect_recv(struct async_req *req)
{
return async_req_simple_recv_wbcerr(req);