diff options
Diffstat (limited to 'source4/lib')
139 files changed, 4822 insertions, 3524 deletions
diff --git a/source4/lib/appweb/ejs/ejsLib.c b/source4/lib/appweb/ejs/ejsLib.c index 0dfc2e0ed2..67d0a4e760 100644 --- a/source4/lib/appweb/ejs/ejsLib.c +++ b/source4/lib/appweb/ejs/ejsLib.c @@ -154,7 +154,7 @@ EjsId ejsOpenEngine(EjsHandle primaryHandle, EjsHandle altHandle) MprVar *np; Ejs *ep; - ep = mprMalloc(sizeof(Ejs)); + ep = (Ejs *)mprMalloc(sizeof(Ejs)); if (ep == 0) { return (EjsId) -1; } diff --git a/source4/lib/basic.mk b/source4/lib/basic.mk index e993207b00..266ca6e685 100644 --- a/source4/lib/basic.mk +++ b/source4/lib/basic.mk @@ -2,7 +2,7 @@ include samba3/config.mk include socket/config.mk include charset/config.mk -include ldb/config.mk +include ldb-samba/config.mk include tls/config.mk include registry/config.mk include policy/config.mk diff --git a/source4/lib/charset/charcnv.c b/source4/lib/charset/charcnv.c index fcf29d4647..9c794202b2 100644 --- a/source4/lib/charset/charcnv.c +++ b/source4/lib/charset/charcnv.c @@ -21,6 +21,7 @@ */ #include "includes.h" #include "system/iconv.h" +#include "param/param.h" /** * @file @@ -37,20 +38,16 @@ * @sa lib/iconv.c */ -char *unix_charset = NULL; -char *dos_charset = NULL; -char *display_charset = NULL; - /** * Return the name of a charset to give to iconv(). **/ -static const char *charset_name(charset_t ch) +static const char *charset_name(struct loadparm_context *lp_ctx, charset_t ch) { switch (ch) { case CH_UTF16: return "UTF-16LE"; - case CH_UNIX: return unix_charset; - case CH_DOS: return dos_charset; - case CH_DISPLAY: return display_charset; + case CH_UNIX: return lp_unix_charset(lp_ctx); + case CH_DOS: return lp_dos_charset(lp_ctx); + case CH_DISPLAY: return lp_display_charset(lp_ctx); case CH_UTF8: return "UTF8"; case CH_UTF16BE: return "UTF-16BE"; default: @@ -108,20 +105,20 @@ static smb_iconv_t get_conv_handle(charset_t from, charset_t to) return conv_handles[from][to]; } - n1 = charset_name(from); - n2 = charset_name(to); + n1 = charset_name(global_loadparm, from); + n2 = charset_name(global_loadparm, to); conv_handles[from][to] = smb_iconv_open(n2,n1); if (conv_handles[from][to] == (smb_iconv_t)-1) { if ((from == CH_DOS || to == CH_DOS) && - strcasecmp(charset_name(CH_DOS), "ASCII") != 0) { + strcasecmp(charset_name(global_loadparm, CH_DOS), "ASCII") != 0) { DEBUG(0,("dos charset '%s' unavailable - using ASCII\n", - charset_name(CH_DOS))); - lp_set_cmdline("dos charset", "ASCII"); + charset_name(global_loadparm, CH_DOS))); + lp_set_cmdline(global_loadparm, "dos charset", "ASCII"); - n1 = charset_name(from); - n2 = charset_name(to); + n1 = charset_name(global_loadparm, from); + n2 = charset_name(global_loadparm, to); conv_handles[from][to] = smb_iconv_open(n2,n1); } @@ -151,7 +148,7 @@ _PUBLIC_ ssize_t convert_string(charset_t from, charset_t to, smb_iconv_t descriptor; if (srclen == (size_t)-1) - srclen = strlen(src)+1; + srclen = strlen(inbuf)+1; descriptor = get_conv_handle(from, to); @@ -175,12 +172,12 @@ _PUBLIC_ ssize_t convert_string(charset_t from, charset_t to, reason="No more room"; if (from == CH_UNIX) { DEBUG(0,("E2BIG: convert_string(%s,%s): srclen=%d destlen=%d - '%s'\n", - charset_name(from), charset_name(to), + charset_name(global_loadparm, from), charset_name(global_loadparm, to), (int)srclen, (int)destlen, (const char *)src)); } else { DEBUG(0,("E2BIG: convert_string(%s,%s): srclen=%d destlen=%d\n", - charset_name(from), charset_name(to), + charset_name(global_loadparm, from), charset_name(global_loadparm, to), (int)srclen, (int)destlen)); } return -1; @@ -222,7 +219,7 @@ _PUBLIC_ ssize_t convert_string_talloc(TALLOC_CTX *ctx, charset_t from, charset_ if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) { /* conversion not supported, return -1*/ DEBUG(3, ("convert_string_talloc: conversion from %s to %s not supported!\n", - charset_name(from), charset_name(to))); + charset_name(global_loadparm, from), charset_name(global_loadparm, to))); return -1; } @@ -350,9 +347,9 @@ static ssize_t pull_ascii(char *dest, const void *src, size_t dest_len, size_t s if (flags & (STR_TERMINATE | STR_TERMINATE_ASCII)) { if (src_len == (size_t)-1) { - src_len = strlen(src) + 1; + src_len = strlen((const char *)src) + 1; } else { - size_t len = strnlen(src, src_len); + size_t len = strnlen((const char *)src, src_len); if (len < src_len) len++; src_len = len; diff --git a/source4/lib/charset/charset.h b/source4/lib/charset/charset.h index 6943a60182..be2705100a 100644 --- a/source4/lib/charset/charset.h +++ b/source4/lib/charset/charset.h @@ -49,7 +49,7 @@ typedef uint32_t codepoint_t; /* generic iconv conversion structure */ -typedef struct { +typedef struct smb_iconv_s { size_t (*direct)(void *cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft); size_t (*pull)(void *cd, const char **inbuf, size_t *inbytesleft, @@ -77,9 +77,4 @@ typedef struct { #define strlower(s) strlower_m(s) #define strupper(s) strupper_m(s) -/* from lib/charset */ -extern char *dos_charset; -extern char *unix_charset; -extern char *display_charset; - #endif /* __CHARSET_H__ */ diff --git a/source4/lib/charset/iconv.c b/source4/lib/charset/iconv.c index 062b4ddfc8..9b035cd1db 100644 --- a/source4/lib/charset/iconv.c +++ b/source4/lib/charset/iconv.c @@ -22,6 +22,7 @@ #include "lib/util/dlinklist.h" #include "system/iconv.h" #include "system/filesys.h" +#include "param/param.h" /** @@ -74,7 +75,7 @@ static struct charset_functions *charsets = NULL; bool charset_register_backend(const void *_funcs) { - struct charset_functions *funcs = memdup(_funcs,sizeof(struct charset_functions)); + struct charset_functions *funcs = (struct charset_functions *)memdup(_funcs,sizeof(struct charset_functions)); struct charset_functions *c; /* Check whether we already have this charset... */ @@ -198,7 +199,7 @@ smb_iconv_t smb_iconv_open(const char *tocode, const char *fromcode) } #ifdef HAVE_NATIVE_ICONV - if ((!from || !to) && !lp_parm_bool(-1, "iconv", "native", true)) { + if ((!from || !to) && !lp_parm_bool(global_loadparm, NULL, "iconv", "native", true)) { goto failed; } if (!from) { diff --git a/source4/lib/charset/util_unistr.c b/source4/lib/charset/util_unistr.c index 6c86b0b899..e9cca090cc 100644 --- a/source4/lib/charset/util_unistr.c +++ b/source4/lib/charset/util_unistr.c @@ -393,7 +393,7 @@ _PUBLIC_ char *strchr_m(const char *s, char c) size_t size; codepoint_t c2 = next_codepoint(s, &size); if (c2 == c) { - return discard_const(s); + return discard_const_p(char, s); } s += size; } @@ -418,7 +418,7 @@ _PUBLIC_ char *strrchr_m(const char *s, char c) size_t size; codepoint_t c2 = next_codepoint(s, &size); if (c2 == c) { - ret = discard_const(s); + ret = discard_const_p(char, s); } s += size; } @@ -482,7 +482,7 @@ _PUBLIC_ char *strlower_talloc(TALLOC_CTX *ctx, const char *src) /* this takes advantage of the fact that upper/lower can't change the length of a character by more than 1 byte */ - dest = talloc_size(ctx, 2*(strlen(src))+1); + dest = talloc_array(ctx, char, 2*(strlen(src))+1); if (dest == NULL) { return NULL; } @@ -505,7 +505,7 @@ _PUBLIC_ char *strlower_talloc(TALLOC_CTX *ctx, const char *src) dest[size] = 0; /* trim it so talloc_append_string() works */ - dest = talloc_realloc_size(ctx, dest, size+1); + dest = talloc_realloc(ctx, dest, char, size+1); talloc_set_name_const(dest, dest); @@ -526,7 +526,7 @@ _PUBLIC_ char *strupper_talloc(TALLOC_CTX *ctx, const char *src) /* this takes advantage of the fact that upper/lower can't change the length of a character by more than 1 byte */ - dest = talloc_size(ctx, 2*(strlen(src))+1); + dest = talloc_array(ctx, char, 2*(strlen(src))+1); if (dest == NULL) { return NULL; } @@ -549,7 +549,7 @@ _PUBLIC_ char *strupper_talloc(TALLOC_CTX *ctx, const char *src) dest[size] = 0; /* trim it so talloc_append_string() works */ - dest = talloc_realloc_size(ctx, dest, size+1); + dest = talloc_realloc(ctx, dest, char, size+1); talloc_set_name_const(dest, dest); diff --git a/source4/lib/cmdline/credentials.c b/source4/lib/cmdline/credentials.c index 36e0504021..2e5c6fd94a 100644 --- a/source4/lib/cmdline/credentials.c +++ b/source4/lib/cmdline/credentials.c @@ -38,7 +38,12 @@ static const char *cmdline_get_userpassword(struct cli_credentials *credentials) return ret; } -void cli_credentials_set_cmdline_callbacks(struct cli_credentials *cred) +bool cli_credentials_set_cmdline_callbacks(struct cli_credentials *cred) { - cli_credentials_set_password_callback(cred, cmdline_get_userpassword); + if (isatty(fileno(stdout))) { + cli_credentials_set_password_callback(cred, cmdline_get_userpassword); + return true; + } + + return false; } diff --git a/source4/lib/cmdline/popt_common.c b/source4/lib/cmdline/popt_common.c index 413c8e7cc3..41eb70094e 100644 --- a/source4/lib/cmdline/popt_common.c +++ b/source4/lib/cmdline/popt_common.c @@ -22,6 +22,8 @@ #include "includes.h" #include "version.h" #include "lib/cmdline/popt_common.h" +#include "param/param.h" +#include "dynconfig.h" /* Handle command line options: * -d,--debuglevel @@ -39,8 +41,6 @@ enum {OPT_OPTION=1,OPT_LEAK_REPORT,OPT_LEAK_REPORT_FULL,OPT_DEBUG_STDERR}; struct cli_credentials *cmdline_credentials = NULL; -static bool PrintSambaVersionString; - static void popt_common_callback(poptContext con, enum poptCallbackReason reason, const struct poptOption *opt, @@ -49,12 +49,12 @@ static void popt_common_callback(poptContext con, const char *pname; if (reason == POPT_CALLBACK_REASON_POST) { - if (PrintSambaVersionString) { - printf( "Version %s\n", SAMBA_VERSION_STRING ); - exit(0); + if (!lp_loaded()) { + if (getenv("SMB_CONF_PATH")) + lp_load(getenv("SMB_CONF_PATH")); + else + lp_load(dyn_CONFIGFILE); } - - lp_load(); /* Hook any 'every Samba program must do this, after * the smb.conf is setup' functions here */ return; @@ -76,15 +76,12 @@ static void popt_common_callback(poptContext con, /* and logging */ setup_logging(pname, DEBUG_STDOUT); - if (getenv("SMB_CONF_PATH")) { - lp_set_cmdline("config file", getenv("SMB_CONF_PATH")); - } return; } switch(opt->val) { case 'd': - lp_set_cmdline("log level", arg); + lp_set_cmdline(global_loadparm, "log level", arg); break; case OPT_DEBUG_STDERR: @@ -92,55 +89,55 @@ static void popt_common_callback(poptContext con, break; case 'V': - PrintSambaVersionString = true; - break; + printf("Version %s\n", SAMBA_VERSION_STRING ); + exit(0); case 'O': if (arg) { - lp_set_cmdline("socket options", arg); + lp_set_cmdline(global_loadparm, "socket options", arg); } break; case 's': if (arg) { - lp_set_cmdline("config file", arg); + lp_load(arg); } break; case 'l': if (arg) { char *new_logfile = talloc_asprintf(NULL, "%s/log.%s", arg, pname); - lp_set_cmdline("log file", new_logfile); + lp_set_cmdline(global_loadparm, "log file", new_logfile); talloc_free(new_logfile); } break; case 'W': - lp_set_cmdline("workgroup", arg); + lp_set_cmdline(global_loadparm, "workgroup", arg); break; case 'r': - lp_set_cmdline("realm", arg); + lp_set_cmdline(global_loadparm, "realm", arg); break; case 'n': - lp_set_cmdline("netbios name", arg); + lp_set_cmdline(global_loadparm, "netbios name", arg); break; case 'i': - lp_set_cmdline("netbios scope", arg); + lp_set_cmdline(global_loadparm, "netbios scope", arg); break; case 'm': - lp_set_cmdline("client max protocol", arg); + lp_set_cmdline(global_loadparm, "client max protocol", arg); break; case 'R': - lp_set_cmdline("name resolve order", arg); + lp_set_cmdline(global_loadparm, "name resolve order", arg); break; case OPT_OPTION: - if (!lp_set_option(arg)) { + if (!lp_set_option(global_loadparm, arg)) { fprintf(stderr, "Error setting option '%s'\n", arg); exit(1); } diff --git a/source4/lib/cmdline/popt_credentials.c b/source4/lib/cmdline/popt_credentials.c index 259dbf8ee1..53e214ab22 100644 --- a/source4/lib/cmdline/popt_credentials.c +++ b/source4/lib/cmdline/popt_credentials.c @@ -23,6 +23,7 @@ #include "lib/cmdline/credentials.h" #include "auth/credentials/credentials.h" #include "auth/gensec/gensec.h" +#include "param/param.h" /* Handle command line options: * -U,--user @@ -36,7 +37,7 @@ */ -static BOOL dont_ask; +static bool dont_ask; enum opt { OPT_SIMPLE_BIND_DN, OPT_PASSWORD, OPT_KERBEROS }; @@ -45,7 +46,7 @@ enum opt { OPT_SIMPLE_BIND_DN, OPT_PASSWORD, OPT_KERBEROS }; */ void popt_common_dont_ask(void) { - dont_ask = True; + dont_ask = true; } static void popt_common_credentials_callback(poptContext con, @@ -94,7 +95,7 @@ static void popt_common_credentials_callback(poptContext con, break; case 'S': - lp_set_cmdline("client signing", arg); + lp_set_cmdline(global_loadparm, "client signing", arg); break; case 'P': @@ -104,7 +105,7 @@ static void popt_common_credentials_callback(poptContext con, case OPT_KERBEROS: { - BOOL use_kerberos = True; + bool use_kerberos = true; /* Force us to only use kerberos */ if (arg) { if (!set_boolean(arg, &use_kerberos)) { diff --git a/source4/lib/crypto/hmacmd5test.c b/source4/lib/crypto/hmacmd5test.c index 3e277a9232..07ed54c98d 100644 --- a/source4/lib/crypto/hmacmd5test.c +++ b/source4/lib/crypto/hmacmd5test.c @@ -31,9 +31,9 @@ static DATA_BLOB data_blob_repeat_byte(uint8_t byte, size_t length) /* This uses the test values from rfc 2104, 2202 */ -BOOL torture_local_crypto_hmacmd5(struct torture_context *torture) +bool torture_local_crypto_hmacmd5(struct torture_context *torture) { - BOOL ret = True; + bool ret = true; uint32_t i; struct { DATA_BLOB key; @@ -90,7 +90,7 @@ BOOL torture_local_crypto_hmacmd5(struct torture_context *torture) dump_data(0, testarray[i].data.data, testarray[i].data.length); dump_data(0, testarray[i].md5.data, testarray[i].md5.length); dump_data(0, md5, sizeof(md5)); - ret = False; + ret = false; } } diff --git a/source4/lib/crypto/hmacsha1test.c b/source4/lib/crypto/hmacsha1test.c index 9c4662a405..6e53124d21 100644 --- a/source4/lib/crypto/hmacsha1test.c +++ b/source4/lib/crypto/hmacsha1test.c @@ -31,9 +31,9 @@ static DATA_BLOB data_blob_repeat_byte(uint8_t byte, size_t length) /* This uses the test values from rfc2202 */ -BOOL torture_local_crypto_hmacsha1(struct torture_context *torture) +bool torture_local_crypto_hmacsha1(struct torture_context *torture) { - BOOL ret = True; + bool ret = true; uint32_t i; struct { DATA_BLOB key; @@ -89,7 +89,7 @@ BOOL torture_local_crypto_hmacsha1(struct torture_context *torture) dump_data(0, testarray[i].data.data, testarray[i].data.length); dump_data(0, testarray[i].sha1.data, testarray[i].sha1.length); dump_data(0, sha1, sizeof(sha1)); - ret = False; + ret = false; } } diff --git a/source4/lib/crypto/md4test.c b/source4/lib/crypto/md4test.c index fa92668f84..5e0451973c 100644 --- a/source4/lib/crypto/md4test.c +++ b/source4/lib/crypto/md4test.c @@ -25,9 +25,9 @@ struct torture_context; /* This uses the test values from rfc1320 */ -BOOL torture_local_crypto_md4(struct torture_context *torture) +bool torture_local_crypto_md4(struct torture_context *torture) { - BOOL ret = True; + bool ret = true; uint32_t i; struct { const char *data; @@ -74,7 +74,7 @@ BOOL torture_local_crypto_md4(struct torture_context *torture) dump_data(0, data.data, data.length); dump_data(0, md4blob.data, md4blob.length); dump_data(0, md4, sizeof(md4)); - ret = False; + ret = false; } talloc_free(md4blob.data); } diff --git a/source4/lib/crypto/md5test.c b/source4/lib/crypto/md5test.c index 12645dc045..702e0fcf41 100644 --- a/source4/lib/crypto/md5test.c +++ b/source4/lib/crypto/md5test.c @@ -25,9 +25,9 @@ struct torture_context; /* This uses the test values from rfc1321 */ -BOOL torture_local_crypto_md5(struct torture_context *torture) +bool torture_local_crypto_md5(struct torture_context *torture) { - BOOL ret = True; + bool ret = true; uint32_t i; struct { const char *data; @@ -84,7 +84,7 @@ BOOL torture_local_crypto_md5(struct torture_context *torture) dump_data(0, data.data, data.length); dump_data(0, md5blob.data, md5blob.length); dump_data(0, md5, sizeof(md5)); - ret = False; + ret = false; } talloc_free(md5blob.data); } diff --git a/source4/lib/crypto/sha1test.c b/source4/lib/crypto/sha1test.c index a37328e328..0e943bd74d 100644 --- a/source4/lib/crypto/sha1test.c +++ b/source4/lib/crypto/sha1test.c @@ -57,7 +57,7 @@ bool torture_local_crypto_sha1(struct torture_context *tctx) struct SHA1Context sha; int i, j, err; uint8_t Message_Digest[20]; - BOOL ret = True; + bool ret = true; char tmp[60 + 10]; /* @@ -94,7 +94,7 @@ bool torture_local_crypto_sha1(struct torture_context *tctx) torture_comment(tctx, "\n"); torture_comment(tctx, "Should match:\n\t%s\n", resultarray[j]); if (strcmp(resultarray[j], tmp) != 0) { - ret = False; + ret = false; } } diff --git a/source4/lib/db_wrap.c b/source4/lib/db_wrap.c index 0e026f84e1..c33786a1e4 100644 --- a/source4/lib/db_wrap.c +++ b/source4/lib/db_wrap.c @@ -32,9 +32,10 @@ #include "lib/tdb/include/tdb.h" #include "lib/ldb/include/ldb.h" #include "lib/ldb/include/ldb_errors.h" -#include "lib/ldb/samba/ldif_handlers.h" +#include "lib/ldb-samba/ldif_handlers.h" #include "db_wrap.h" #include "dsdb/samdb/samdb.h" +#include "param/param.h" static struct tdb_wrap *tdb_list; @@ -102,6 +103,7 @@ static int ldb_wrap_destructor(struct ldb_context *ldb) TODO: We need an error_string parameter */ struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, const char *url, struct auth_session_info *session_info, struct cli_credentials *credentials, @@ -119,6 +121,9 @@ struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx, return NULL; } + ldb_set_modules_dir(ldb, + talloc_asprintf(ldb, "%s/ldb", lp_modulesdir(lp_ctx))); + /* we want to use the existing event context if possible. This relies on the fact that in smbd, everything is a child of the main event_context */ @@ -139,7 +144,7 @@ struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx, return NULL; } - if (strcmp(lp_sam_url(), url) == 0) { + if (strcmp(lp_sam_url(lp_ctx), url) == 0) { dsdb_set_global_schema(ldb); } @@ -153,14 +158,14 @@ struct ldb_context *ldb_wrap_connect(TALLOC_CTX *mem_ctx, ldb_set_utf8_fns(ldb, NULL, wrap_casefold); - real_url = private_path(ldb, url); + real_url = private_path(ldb, lp_ctx, url); if (real_url == NULL) { talloc_free(ldb); return NULL; } /* allow admins to force non-sync ldb for all databases */ - if (lp_parm_bool(-1, "ldb", "nosync", False)) { + if (lp_parm_bool(lp_ctx, NULL, "ldb", "nosync", false)) { flags |= LDB_FLG_NOSYNC; } diff --git a/source4/lib/db_wrap.h b/source4/lib/db_wrap.h index 4ead9f3010..b45a05c24f 100644 --- a/source4/lib/db_wrap.h +++ b/source4/lib/db_wrap.h @@ -31,5 +31,6 @@ struct auth_session_info; struct ldb_message; struct ldb_dn; struct cli_credentials; +struct loadparm_context; #include "lib/db_wrap_proto.h" diff --git a/source4/lib/dbwrap/dbwrap.c b/source4/lib/dbwrap/dbwrap.c index c0bac672aa..9e893b1243 100644 --- a/source4/lib/dbwrap/dbwrap.c +++ b/source4/lib/dbwrap/dbwrap.c @@ -23,14 +23,15 @@ #include "includes.h" #include "lib/tdb/include/tdb.h" #include "lib/dbwrap/dbwrap.h" +#include "param/param.h" /* open a temporary database */ struct db_context *db_tmp_open(TALLOC_CTX *mem_ctx, const char *name, int tdb_flags) { - if (lp_parm_bool(-1, "ctdb", "enable", False) && - lp_parm_bool(-1, "ctdb", name, True)) { + if (lp_parm_bool(global_loadparm, NULL, "ctdb", "enable", false) && + lp_parm_bool(global_loadparm, NULL, "ctdb", name, true)) { return db_tmp_open_ctdb(mem_ctx, name, tdb_flags); } diff --git a/source4/lib/dbwrap/dbwrap_tdb.c b/source4/lib/dbwrap/dbwrap_tdb.c index dedb344e0b..b256b6ccc4 100644 --- a/source4/lib/dbwrap/dbwrap_tdb.c +++ b/source4/lib/dbwrap/dbwrap_tdb.c @@ -25,6 +25,7 @@ #include "lib/dbwrap/dbwrap.h" #include "system/filesys.h" #include "db_wrap.h" +#include "param/param.h" struct db_tdb_ctx { struct tdb_wrap *wtdb; @@ -240,7 +241,7 @@ struct db_context *db_tmp_open_tdb(TALLOC_CTX *mem_ctx, const char *name, int td /* the name passed in should not be a full path, it should be just be the db name */ - path = smbd_tmp_path(result, name); + path = smbd_tmp_path(result, global_loadparm, name); db_tdb->wtdb = tdb_wrap_open(db_tdb, path, 0, tdb_flags, O_CREAT|O_RDWR, 0666); diff --git a/source4/lib/events/events.c b/source4/lib/events/events.c index 9ba3254190..2b36c92491 100644 --- a/source4/lib/events/events.c +++ b/source4/lib/events/events.c @@ -57,6 +57,7 @@ #include "lib/events/events.h" #include "lib/events/events_internal.h" #include "lib/util/dlinklist.h" +#include "param/param.h" #if _SAMBA_BUILD_ #include "build.h" #endif @@ -79,11 +80,11 @@ bool event_register_backend(const char *name, const struct event_ops *ops) { struct event_ops_list *e; e = talloc(talloc_autofree_context(), struct event_ops_list); - if (e == NULL) return False; + if (e == NULL) return false; e->name = name; e->ops = ops; DLIST_ADD(event_backends, e); - return True; + return true; } /* @@ -104,7 +105,7 @@ static void event_backend_init(void) init_module_fn static_init[] = STATIC_LIBEVENTS_MODULES; init_module_fn *shared_init; if (event_backends) return; - shared_init = load_samba_modules(NULL, "LIBEVENTS"); + shared_init = load_samba_modules(NULL, global_loadparm, "events"); run_init_functions(static_init); run_init_functions(shared_init); #else @@ -184,7 +185,7 @@ struct event_context *event_context_init_byname(TALLOC_CTX *mem_ctx, const char #if _SAMBA_BUILD_ if (name == NULL) { - name = lp_parm_string(-1, "event", "backend"); + name = lp_parm_string(global_loadparm, NULL, "event", "backend"); } #endif if (name == NULL) { diff --git a/source4/lib/events/events_epoll.c b/source4/lib/events/events_epoll.c index acd204c898..e2212e5333 100644 --- a/source4/lib/events/events_epoll.c +++ b/source4/lib/events/events_epoll.c @@ -56,7 +56,7 @@ struct epoll_event_context { called when a epoll call fails, and we should fallback to using select */ -static void epoll_panic(struct epoll_event_context *epoll_ev, const char *reason) +_NORETURN_ static void epoll_panic(struct epoll_event_context *epoll_ev, const char *reason) { DEBUG(0,("%s (%s) - calling abort()\n", reason, strerror(errno))); abort(); diff --git a/source4/lib/events/events_signal.c b/source4/lib/events/events_signal.c index 2f6d499383..aec34339c3 100644 --- a/source4/lib/events/events_signal.c +++ b/source4/lib/events/events_signal.c @@ -217,8 +217,8 @@ struct signal_event *common_event_add_signal(struct event_context *ev, if (sig_state->pipe_hack[0] == 0 && sig_state->pipe_hack[1] == 0) { pipe(sig_state->pipe_hack); - set_blocking(sig_state->pipe_hack[0], False); - set_blocking(sig_state->pipe_hack[1], False); + set_blocking(sig_state->pipe_hack[0], false); + set_blocking(sig_state->pipe_hack[1], false); } ev->pipe_fde = event_add_fd(ev, ev, sig_state->pipe_hack[0], EVENT_FD_READ, signal_pipe_handler, NULL); diff --git a/source4/lib/gencache/gencache.c b/source4/lib/gencache/gencache.c index a30f09fefa..949b16cb3b 100644 --- a/source4/lib/gencache/gencache.c +++ b/source4/lib/gencache/gencache.c @@ -47,30 +47,31 @@ static struct tdb_wrap *cache; * false on failure **/ -BOOL gencache_init(void) +bool gencache_init(void) { char* cache_fname = NULL; + TALLOC_CTX *mem_ctx = talloc_autofree_context(); /* skip file open if it's already opened */ - if (cache) return True; + if (cache) return true; - asprintf(&cache_fname, "%s/%s", lp_lockdir(), "gencache.tdb"); - if (cache_fname) + cache_fname = lock_path(mem_ctx, global_loadparm, "gencache.tdb"); + if (cache_fname != NULL) { DEBUG(5, ("Opening cache file at %s\n", cache_fname)); - else { + } else { DEBUG(0, ("Filename allocation failed.\n")); - return False; + return false; } - cache = tdb_wrap_open(NULL, cache_fname, 0, TDB_DEFAULT, + cache = tdb_wrap_open(mem_ctx, cache_fname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644); - SAFE_FREE(cache_fname); + talloc_free(cache_fname); if (!cache) { DEBUG(5, ("Attempt to open gencache.tdb has failed.\n")); - return False; + return false; } - return True; + return true; } @@ -81,12 +82,12 @@ BOOL gencache_init(void) * false on failure during cache shutdown **/ -BOOL gencache_shutdown(void) +bool gencache_shutdown(void) { - if (!cache) return False; + if (!cache) return false; DEBUG(5, ("Closing cache file\n")); talloc_free(cache); - return True; + return true; } @@ -102,7 +103,7 @@ BOOL gencache_shutdown(void) * @retval false on failure **/ -BOOL gencache_set(const char *keystr, const char *value, time_t timeout) +bool gencache_set(const char *keystr, const char *value, time_t timeout) { int ret; TDB_DATA keybuf, databuf; @@ -111,11 +112,11 @@ BOOL gencache_set(const char *keystr, const char *value, time_t timeout) /* fail completely if get null pointers passed */ SMB_ASSERT(keystr && value); - if (!gencache_init()) return False; + if (!gencache_init()) return false; asprintf(&valstr, CACHE_DATA_FMT, (int)timeout, value); if (!valstr) - return False; + return false; keybuf.dptr = (uint8_t *)strdup(keystr); keybuf.dsize = strlen(keystr)+1; @@ -145,7 +146,7 @@ BOOL gencache_set(const char *keystr, const char *value, time_t timeout) * @retval false on failure **/ -BOOL gencache_set_only(const char *keystr, const char *valstr, time_t timeout) +bool gencache_set_only(const char *keystr, const char *valstr, time_t timeout) { int ret = -1; TDB_DATA keybuf, databuf; @@ -155,7 +156,7 @@ BOOL gencache_set_only(const char *keystr, const char *valstr, time_t timeout) /* fail completely if get null pointers passed */ SMB_ASSERT(keystr && valstr); - if (!gencache_init()) return False; + if (!gencache_init()) return false; /* * Check whether entry exists in the cache @@ -163,7 +164,7 @@ BOOL gencache_set_only(const char *keystr, const char *valstr, time_t timeout) */ gencache_get(keystr, &old_valstr, &old_timeout); - if (!(old_valstr && old_timeout)) return False; + if (!(old_valstr && old_timeout)) return false; DEBUG(10, ("Setting cache entry with key = %s; old value = %s and old timeout \ = %s\n", keystr, old_valstr, ctime(&old_timeout))); @@ -198,7 +199,7 @@ BOOL gencache_set_only(const char *keystr, const char *valstr, time_t timeout) * @retval false in case of failure **/ -BOOL gencache_del(const char *keystr) +bool gencache_del(const char *keystr) { int ret; TDB_DATA keybuf; @@ -206,7 +207,7 @@ BOOL gencache_del(const char *keystr) /* fail completely if get null pointers passed */ SMB_ASSERT(keystr); - if (!gencache_init()) return False; + if (!gencache_init()) return false; keybuf.dptr = (uint8_t *)strdup(keystr); keybuf.dsize = strlen(keystr)+1; @@ -228,10 +229,10 @@ BOOL gencache_del(const char *keystr) * timeout * * @retval true when entry is successfuly fetched - * @retval False for failure + * @retval false for failure **/ -BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout) +bool gencache_get(const char *keystr, char **valstr, time_t *timeout) { TDB_DATA keybuf, databuf; @@ -239,7 +240,7 @@ BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout) SMB_ASSERT(keystr); if (!gencache_init()) - return False; + return false; keybuf.dptr = (uint8_t *)strdup(keystr); keybuf.dsize = strlen(keystr)+1; @@ -285,7 +286,7 @@ BOOL gencache_get(const char *keystr, char **valstr, time_t *timeout) DEBUG(10, ("Cache entry with key = %s couldn't be found\n", keystr)); - return False; + return false; } } diff --git a/source4/lib/ldb/samba/README b/source4/lib/ldb-samba/README index 3fa47159ca..3fa47159ca 100644 --- a/source4/lib/ldb/samba/README +++ b/source4/lib/ldb-samba/README diff --git a/source4/lib/ldb/samba/config.mk b/source4/lib/ldb-samba/config.mk index d29b3f319c..d29b3f319c 100644 --- a/source4/lib/ldb/samba/config.mk +++ b/source4/lib/ldb-samba/config.mk diff --git a/source4/lib/ldb/samba/ldif_handlers.c b/source4/lib/ldb-samba/ldif_handlers.c index cfd79563d5..928a06ab43 100644 --- a/source4/lib/ldb/samba/ldif_handlers.c +++ b/source4/lib/ldb-samba/ldif_handlers.c @@ -78,15 +78,15 @@ static int ldif_write_objectSid(struct ldb_context *ldb, void *mem_ctx, return 0; } -static BOOL ldb_comparision_objectSid_isString(const struct ldb_val *v) +static bool ldb_comparision_objectSid_isString(const struct ldb_val *v) { if (v->length < 3) { - return False; + return false; } - if (strncmp("S-", (const char *)v->data, 2) != 0) return False; + if (strncmp("S-", (const char *)v->data, 2) != 0) return false; - return True; + return true; } /* @@ -176,22 +176,22 @@ static int ldif_write_objectGUID(struct ldb_context *ldb, void *mem_ctx, return 0; } -static BOOL ldb_comparision_objectGUID_isString(const struct ldb_val *v) +static bool ldb_comparision_objectGUID_isString(const struct ldb_val *v) { struct GUID guid; NTSTATUS status; - if (v->length < 33) return False; + if (v->length < 33) return false; /* see if the input if null-terninated (safety check for the below) */ - if (v->data[v->length] != '\0') return False; + if (v->data[v->length] != '\0') return false; status = GUID_from_string((const char *)v->data, &guid); if (!NT_STATUS_IS_OK(status)) { - return False; + return false; } - return True; + return true; } /* diff --git a/source4/lib/ldb/Makefile.in b/source4/lib/ldb/Makefile.in index 4a4585d861..75f1767550 100644 --- a/source4/lib/ldb/Makefile.in +++ b/source4/lib/ldb/Makefile.in @@ -30,11 +30,14 @@ POPT_LIBS = @POPT_LIBS@ POPT_CFLAGS = @POPT_CFLAGS@ POPT_OBJ = @POPT_OBJ@ +LDAP_LIBS = @LDAP_LIBS@ + CFLAGS=-g -I$(srcdir)/include -Iinclude -I$(srcdir) -I$(srcdir)/.. \ $(POPT_CFLAGS) $(TALLOC_CFLAGS) $(TDB_CFLAGS) \ -DLIBDIR=\"$(libdir)\" -DSHLIBEXT=\"@SHLIBEXT@\" -DUSE_MMAP=1 @CFLAGS@ -LIB_FLAGS=@LDFLAGS@ -Llib -lldb @LIBS@ $(POPT_LIBS) $(TALLOC_LIBS) $(TDB_LIBS) +LIB_FLAGS=@LDFLAGS@ -Llib -lldb @LIBS@ $(POPT_LIBS) $(TALLOC_LIBS) $(TDB_LIBS) \ + $(LDAP_LIBS) LDB_TDB_DIR=ldb_tdb LDB_TDB_OBJ=$(LDB_TDB_DIR)/ldb_tdb.o \ diff --git a/source4/lib/ldb/common/attrib_handlers.c b/source4/lib/ldb/common/attrib_handlers.c index b8747c3b95..8ed2763d4d 100644 --- a/source4/lib/ldb/common/attrib_handlers.c +++ b/source4/lib/ldb/common/attrib_handlers.c @@ -278,33 +278,6 @@ int ldb_comparison_dn(struct ldb_context *ldb, void *mem_ctx, } /* - compare two objectclasses, looking at subclasses -*/ -int ldb_comparison_objectclass(struct ldb_context *ldb, void *mem_ctx, - const struct ldb_val *v1, const struct ldb_val *v2) -{ - int ret, i; - const char **subclasses; - ret = ldb_comparison_fold(ldb, mem_ctx, v1, v2); - if (ret == 0) { - return 0; - } - subclasses = ldb_subclass_list(ldb, (char *)v1->data); - if (subclasses == NULL) { - return ret; - } - for (i=0;subclasses[i];i++) { - struct ldb_val vs; - vs.data = discard_const(subclasses[i]); - vs.length = strlen(subclasses[i]); - if (ldb_comparison_objectclass(ldb, mem_ctx, &vs, v2) == 0) { - return 0; - } - } - return ret; -} - -/* compare two utc time values. 1 second resolution */ int ldb_comparison_utctime(struct ldb_context *ldb, void *mem_ctx, @@ -368,7 +341,7 @@ static const struct ldb_schema_syntax ldb_standard_syntaxes[] = { .ldif_read_fn = ldb_handler_copy, .ldif_write_fn = ldb_handler_copy, .canonicalise_fn = ldb_handler_fold, - .comparison_fn = ldb_comparison_objectclass + .comparison_fn = ldb_comparison_fold }, { .name = LDB_SYNTAX_UTC_TIME, diff --git a/source4/lib/ldb/common/ldb.c b/source4/lib/ldb/common/ldb.c index f8085d213a..eb8ff62a0d 100644 --- a/source4/lib/ldb/common/ldb.c +++ b/source4/lib/ldb/common/ldb.c @@ -51,6 +51,7 @@ struct ldb_context *ldb_init(void *mem_ctx) ldb_set_utf8_default(ldb); ldb_set_create_perms(ldb, 0666); + ldb_set_modules_dir(ldb, LDB_MODULESDIR); return ldb; } diff --git a/source4/lib/ldb/common/ldb_attributes.c b/source4/lib/ldb/common/ldb_attributes.c index 358d2f18bd..effd93ae26 100644 --- a/source4/lib/ldb/common/ldb_attributes.c +++ b/source4/lib/ldb/common/ldb_attributes.c @@ -204,114 +204,3 @@ int ldb_setup_wellknown_attributes(struct ldb_context *ldb) return LDB_SUCCESS; } -/* - return the list of subclasses for a class -*/ -const char **ldb_subclass_list(struct ldb_context *ldb, const char *classname) -{ - int i; - for (i=0;i<ldb->schema.num_classes;i++) { - if (ldb_attr_cmp(classname, ldb->schema.classes[i].name) == 0) { - return (const char **)ldb->schema.classes[i].subclasses; - } - } - return NULL; -} - - -/* - add a new subclass -*/ -static int ldb_subclass_new(struct ldb_context *ldb, const char *classname, const char *subclass) -{ - struct ldb_subclass *s, *c; - s = talloc_realloc(ldb, ldb->schema.classes, struct ldb_subclass, ldb->schema.num_classes+1); - if (s == NULL) goto failed; - - ldb->schema.classes = s; - c = &s[ldb->schema.num_classes]; - c->name = talloc_strdup(s, classname); - if (c->name == NULL) goto failed; - - c->subclasses = talloc_array(s, char *, 2); - if (c->subclasses == NULL) goto failed; - - c->subclasses[0] = talloc_strdup(c->subclasses, subclass); - if (c->subclasses[0] == NULL) goto failed; - c->subclasses[1] = NULL; - - ldb->schema.num_classes++; - - return 0; -failed: - ldb_oom(ldb); - return -1; -} - -/* - add a subclass -*/ -int ldb_subclass_add(struct ldb_context *ldb, const char *classname, const char *subclass) -{ - int i, n; - struct ldb_subclass *c; - char **s; - - for (i=0;i<ldb->schema.num_classes;i++) { - if (ldb_attr_cmp(classname, ldb->schema.classes[i].name) == 0) { - break; - } - } - if (i == ldb->schema.num_classes) { - return ldb_subclass_new(ldb, classname, subclass); - } - c = &ldb->schema.classes[i]; - - for (n=0;c->subclasses[n];n++) /* noop */; - - s = talloc_realloc(ldb->schema.classes, c->subclasses, char *, n+2); - if (s == NULL) { - ldb_oom(ldb); - return -1; - } - - c->subclasses = s; - s[n] = talloc_strdup(s, subclass); - if (s[n] == NULL) { - ldb_oom(ldb); - return -1; - } - s[n+1] = NULL; - - return 0; -} - -/* - remove a set of subclasses for a class -*/ -void ldb_subclass_remove(struct ldb_context *ldb, const char *classname) -{ - int i; - struct ldb_subclass *c; - - for (i=0;i<ldb->schema.num_classes;i++) { - if (ldb_attr_cmp(classname, ldb->schema.classes[i].name) == 0) { - break; - } - } - if (i == ldb->schema.num_classes) { - return; - } - - c = &ldb->schema.classes[i]; - talloc_free(c->name); - talloc_free(c->subclasses); - if (ldb->schema.num_classes-(i+1) > 0) { - memmove(c, c+1, sizeof(*c) * (ldb->schema.num_classes-(i+1))); - } - ldb->schema.num_classes--; - if (ldb->schema.num_classes == 0) { - talloc_free(ldb->schema.classes); - ldb->schema.classes = NULL; - } -} diff --git a/source4/lib/ldb/common/ldb_dn.c b/source4/lib/ldb/common/ldb_dn.c index 41e70cffd1..f0bd72e009 100644 --- a/source4/lib/ldb/common/ldb_dn.c +++ b/source4/lib/ldb/common/ldb_dn.c @@ -1279,6 +1279,7 @@ static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) { int i; TALLOC_CTX *tmpctx; char *cracked = NULL; + const char *format = (ex_format ? "\n" : "/" ); if ( ! ldb_dn_validate(dn)) { return NULL; @@ -1305,32 +1306,23 @@ static char *ldb_dn_canonical(void *mem_ctx, struct ldb_dn *dn, int ex_format) { /* Only domain components? Finish here */ if (i < 0) { - if (ex_format) { - cracked = talloc_append_string(tmpctx, cracked, "\n"); - } else { - cracked = talloc_append_string(tmpctx, cracked, "/"); - } + cracked = talloc_strdup_append_buffer(cracked, format); talloc_steal(mem_ctx, cracked); goto done; } /* Now walk backwards appending remaining components */ for (; i > 0; i--) { - cracked = talloc_asprintf_append(cracked, "/%s", - ldb_dn_escape_value(tmpctx, dn->components[i].value)); + cracked = talloc_asprintf_append_buffer(cracked, "/%s", + ldb_dn_escape_value(tmpctx, dn->components[i].value)); if (!cracked) { goto done; } } /* Last one, possibly a newline for the 'ex' format */ - if (ex_format) { - cracked = talloc_asprintf_append(cracked, "\n%s", - ldb_dn_escape_value(tmpctx, dn->components[i].value)); - } else { - cracked = talloc_asprintf_append(cracked, "/%s", - ldb_dn_escape_value(tmpctx, dn->components[i].value)); - } + cracked = talloc_asprintf_append_buffer(cracked, "%s%s", format, + ldb_dn_escape_value(tmpctx, dn->components[i].value)); talloc_steal(mem_ctx, cracked); done: diff --git a/source4/lib/ldb/common/ldb_modules.c b/source4/lib/ldb/common/ldb_modules.c index 2c9fba590a..9f94c90c92 100644 --- a/source4/lib/ldb/common/ldb_modules.c +++ b/source4/lib/ldb/common/ldb_modules.c @@ -36,12 +36,17 @@ #if (_SAMBA_BUILD_ >= 4) #include "includes.h" #include "build.h" -#include "dynconfig.h" #endif #define LDB_MODULE_PREFIX "modules:" #define LDB_MODULE_PREFIX_LEN 8 +void ldb_set_modules_dir(struct ldb_context *ldb, const char *path) +{ + talloc_free(ldb->modules_dir); + ldb->modules_dir = talloc_strdup(ldb, path); +} + static char *ldb_modules_strdup_no_spaces(TALLOC_CTX *mem_ctx, const char *string) { int i, len; @@ -203,21 +208,12 @@ int ldb_try_load_dso(struct ldb_context *ldb, const char *name) char *path; void *handle; int (*init_fn) (void); - char *modulesdir; - if (getenv("LD_LDB_MODULE_PATH") != NULL) { - modulesdir = talloc_strdup(ldb, getenv("LD_LDB_MODULE_PATH")); - } else { -#ifdef _SAMBA_BUILD_ - modulesdir = talloc_asprintf(ldb, "%s/ldb", dyn_MODULESDIR); -#else - modulesdir = talloc_strdup(ldb, MODULESDIR); -#endif - } - - path = talloc_asprintf(ldb, "%s/%s.%s", modulesdir, name, SHLIBEXT); + if (ldb->modules_dir == NULL) + return -1; - talloc_free(modulesdir); + path = talloc_asprintf(ldb, "%s/%s.%s", ldb->modules_dir, name, + SHLIBEXT); ldb_debug(ldb, LDB_DEBUG_TRACE, "trying to load %s from %s\n", name, path); diff --git a/source4/lib/ldb/config.mk b/source4/lib/ldb/config.mk index e47bf8ea39..6472612837 100644 --- a/source4/lib/ldb/config.mk +++ b/source4/lib/ldb/config.mk @@ -71,24 +71,10 @@ OBJ_FILES = \ ################################################ ################################################ -# Start MODULE ldb_ildap -[MODULE::ldb_ildap] -SUBSYSTEM = LIBLDB -CFLAGS = -Ilib/ldb/include -PRIVATE_DEPENDENCIES = LIBTALLOC LIBCLI_LDAP -INIT_FUNCTION = ldb_ildap_init -ALIASES = ldapi ldaps ldap -OBJ_FILES = \ - ldb_ildap/ldb_ildap.o -# End MODULE ldb_ildap -################################################ - -################################################ # Start MODULE ldb_map -[MODULE::ldb_map] +[SUBSYSTEM::ldb_map] PRIVATE_DEPENDENCIES = LIBTALLOC CFLAGS = -Ilib/ldb/include -Ilib/ldb/ldb_map -SUBSYSTEM = LIBLDB OBJ_FILES = \ ldb_map/ldb_map_inbound.o \ ldb_map/ldb_map_outbound.o \ @@ -137,14 +123,6 @@ PRIVATE_DEPENDENCIES = \ # End MODULE ldb_tdb ################################################ -# NOTE: this rule is broken for some systems when $builddir != $srcdir because -# it hardcodes the use of $<. See smb_build/makefile.pm. -./lib/ldb/common/ldb_modules.o: lib/ldb/common/ldb_modules.c Makefile - @echo Compiling $< - @$(CC) `$(PERL) $(srcdir)/script/cflags.pl $@` $(CFLAGS) $(PICFLAG) \ - -DLDBMODULESDIR=\"$(MODULESDIR)/ldb\" -DSHLIBEXT=\"$(SHLIBEXT)\" \ - -c $< -o $@ - ################################################ # Start SUBSYSTEM ldb [LIBRARY::LIBLDB] @@ -179,89 +157,6 @@ PUBLIC_HEADERS = include/ldb.h include/ldb_errors.h ################################################ ################################################ -# Start SUBSYSTEM LIBLDB_CMDLINE -[SUBSYSTEM::LIBLDB_CMDLINE] -CFLAGS = -Ilib/ldb -OBJ_FILES= \ - tools/cmdline.o -PUBLIC_DEPENDENCIES = LIBLDB LIBPOPT -PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL POPT_SAMBA POPT_CREDENTIALS gensec -# End SUBSYSTEM LIBLDB_CMDLINE -################################################ - -################################################ -# Start BINARY ldbadd -[BINARY::ldbadd] -INSTALLDIR = BINDIR -OBJ_FILES = \ - tools/ldbadd.o -PRIVATE_DEPENDENCIES = \ - LIBLDB_CMDLINE LIBCLI_RESOLVE -MANPAGE = man/ldbadd.1 -# End BINARY ldbadd -################################################ - -################################################ -# Start BINARY ldbdel -[BINARY::ldbdel] -INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/ldbdel.o -PRIVATE_DEPENDENCIES = \ - LIBLDB_CMDLINE -MANPAGE = man/ldbdel.1 -# End BINARY ldbdel -################################################ - -################################################ -# Start BINARY ldbmodify -[BINARY::ldbmodify] -INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/ldbmodify.o -PRIVATE_DEPENDENCIES = \ - LIBLDB_CMDLINE -MANPAGE = man/ldbmodify.1 -# End BINARY ldbmodify -################################################ - -################################################ -# Start BINARY ldbsearch -[BINARY::ldbsearch] -INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/ldbsearch.o -PRIVATE_DEPENDENCIES = \ - LIBLDB_CMDLINE -MANPAGE = man/ldbsearch.1 -# End BINARY ldbsearch -################################################ - -################################################ -# Start BINARY ldbedit -[BINARY::ldbedit] -INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/ldbedit.o -PRIVATE_DEPENDENCIES = \ - LIBLDB_CMDLINE -MANPAGE = man/ldbedit.1 -# End BINARY ldbedit -################################################ - -################################################ -# Start BINARY ldbrename -[BINARY::ldbrename] -INSTALLDIR = BINDIR -OBJ_FILES= \ - tools/ldbrename.o -PRIVATE_DEPENDENCIES = \ - LIBLDB_CMDLINE -MANPAGE = man/ldbrename.1 -# End BINARY ldbrename -################################################ - -################################################ # Start BINARY ldbtest [BINARY::ldbtest] OBJ_FILES= \ @@ -306,4 +201,5 @@ OBJ_FILES = swig/ldb_wrap.o # End LIBRARY swig_ldb ####################### -include samba/config.mk +include tools/config.mk +include ldb_ildap/config.mk diff --git a/source4/lib/ldb/configure.ac b/source4/lib/ldb/configure.ac index 083518474d..6f19d88290 100644 --- a/source4/lib/ldb/configure.ac +++ b/source4/lib/ldb/configure.ac @@ -11,7 +11,7 @@ AC_DEFUN([SMB_MODULE_DEFAULT], [echo -n ""]) AC_DEFUN([SMB_LIBRARY_ENABLE], [echo -n ""]) AC_DEFUN([SMB_EXT_LIB], [echo -n ""]) AC_DEFUN([SMB_ENABLE], [echo -n ""]) -AC_INIT(ldb, 0.9.0) +AC_INIT(ldb, 0.9.1) AC_CONFIG_SRCDIR([common/ldb.c]) AC_LIBREPLACE_ALL_CHECKS @@ -41,8 +41,8 @@ AC_SEARCH_LIBS(dlopen, dl, AC_DEFINE(HAVE_DLOPEN, [1], [have dlopen])) SHLIBEXT="so" # Should be set based on OS later on AC_SUBST(SHLIBEXT) -AC_DEFINE_UNQUOTED(MODULESDIR, LIBDIR "/ldb" , [Modules directory] ) -AC_SUBST(MODULESDIR) +AC_DEFINE_UNQUOTED(LDB_MODULESDIR, LIBDIR "/ldb" , [Modules directory] ) +AC_SUBST(LDB_MODULESDIR) TESTS="" EXTRA_OBJ="" @@ -53,9 +53,10 @@ m4_include(libtdb.m4) m4_include(ldap.m4) if test x"$with_ldap_support" = x"yes"; then - LIBS="$LIBS -llber -lldap" CFLAGS="$CFLAGS -DHAVE_LDB_LDAP=1" EXTRA_OBJ="$EXTRA_OBJ ldb_ldap/ldb_ldap.o" + LDAP_LIBS="-llber -lldap" + AC_SUBST(LDAP_LIBS) TESTS="$TESTS test-ldap.sh" fi diff --git a/source4/lib/ldb/include/ldb.h b/source4/lib/ldb/include/ldb.h index 8f693309c5..41d23b5d10 100644 --- a/source4/lib/ldb/include/ldb.h +++ b/source4/lib/ldb/include/ldb.h @@ -779,6 +779,7 @@ int ldb_wait(struct ldb_handle *handle, enum ldb_wait_type type); int ldb_set_timeout(struct ldb_context *ldb, struct ldb_request *req, int timeout); int ldb_set_timeout_from_prev_req(struct ldb_context *ldb, struct ldb_request *oldreq, struct ldb_request *newreq); void ldb_set_create_perms(struct ldb_context *ldb, unsigned int perms); +void ldb_set_modules_dir(struct ldb_context *ldb, const char *path); /** Initialise ldbs' global information @@ -876,7 +877,7 @@ int ldb_search_default_callback(struct ldb_context *ldb, void *context, struct l \param ret_req the request structure is returned here (talloced on mem_ctx) \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc emmory context (used as parent of ret_req) + \param mem_ctx a talloc memory context (used as parent of ret_req) \param base the Base Distinguished Name for the query (use ldb_dn_new() for an empty one) \param scope the search scope for the query \param expression the search expression to use for this query @@ -904,7 +905,7 @@ int ldb_build_search_req(struct ldb_request **ret_req, \param ret_req the request structure is returned here (talloced on mem_ctx) \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc emmory context (used as parent of ret_req) + \param mem_ctx a talloc memory context (used as parent of ret_req) \param message contains the entry to be added \param controls an array of controls \param context the callback function context @@ -926,7 +927,7 @@ int ldb_build_add_req(struct ldb_request **ret_req, \param ret_req the request structure is returned here (talloced on mem_ctx) \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc emmory context (used as parent of ret_req) + \param mem_ctx a talloc memory context (used as parent of ret_req) \param message contains the entry to be modified \param controls an array of controls \param context the callback function context @@ -948,7 +949,7 @@ int ldb_build_mod_req(struct ldb_request **ret_req, \param ret_req the request structure is returned here (talloced on mem_ctx) \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc emmory context (used as parent of ret_req) + \param mem_ctx a talloc memory context (used as parent of ret_req) \param dn the DN to be deleted \param controls an array of controls \param context the callback function context @@ -970,7 +971,7 @@ int ldb_build_del_req(struct ldb_request **ret_req, \param ret_req the request structure is returned here (talloced on mem_ctx) \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc emmory context (used as parent of ret_req) + \param mem_ctx a talloc memory context (used as parent of ret_req) \param olddn the old DN \param newdn the new DN \param controls an array of controls @@ -1043,15 +1044,6 @@ int ldb_search_exp_fmt(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, enum ldb_scope scope, const char * const *attrs, const char *exp_fmt, ...) PRINTF_ATTRIBUTE(7,8); -/* - like ldb_search() but takes a parse tree -*/ -int ldb_search_bytree(struct ldb_context *ldb, - struct ldb_dn *base, - enum ldb_scope scope, - struct ldb_parse_tree *tree, - const char * const *attrs, struct ldb_result **res); - /** Add a record to the database. @@ -1137,7 +1129,7 @@ int ldb_extended_default_callback(struct ldb_context *ldb, void *context, struct \param ret_req the request structure is returned here (talloced on mem_ctx) \param ldb the context associated with the database (from ldb_init()) - \param mem_ctx a talloc emmory context (used as parent of ret_req) + \param mem_ctx a talloc memory context (used as parent of ret_req) \param oid the OID of the extended operation. \param data a void pointer a the extended operation specific parameters, it needs to be NULL or a valid talloc pointer! talloc_get_type() will be used on it @@ -1418,9 +1410,6 @@ bool ldb_dn_check_special(struct ldb_dn *dn, const char *check); bool ldb_dn_is_null(struct ldb_dn *dn); -/* useful functions for ldb_message structure manipulation */ -int ldb_dn_cmp(struct ldb_context *ldb, const char *dn1, const char *dn2); - /** Compare two attributes diff --git a/source4/lib/ldb/include/ldb_private.h b/source4/lib/ldb/include/ldb_private.h index cac665b5bb..e07083bef7 100644 --- a/source4/lib/ldb/include/ldb_private.h +++ b/source4/lib/ldb/include/ldb_private.h @@ -120,6 +120,8 @@ struct ldb_context { unsigned int flags; unsigned int create_perms; + + char *modules_dir; }; #ifndef ARRAY_SIZE diff --git a/source4/lib/ldb/ldb.pc.in b/source4/lib/ldb/ldb.pc.in index fb59f82698..248fb05c4f 100644 --- a/source4/lib/ldb/ldb.pc.in +++ b/source4/lib/ldb/ldb.pc.in @@ -10,6 +10,7 @@ Version: @PACKAGE_VERSION@ Requires.private: tdb Requires: talloc Libs: -L${libdir} -lldb -Cflags: -I${includedir} @CFLAGS@ +Libs.private: @LDAP_LIBS@ +Cflags: -I${includedir} Modulesdir: ${modulesdir} URL: http://ldb.samba.org/ diff --git a/source4/lib/ldb/ldb_ildap/config.mk b/source4/lib/ldb/ldb_ildap/config.mk new file mode 100644 index 0000000000..71887c14f8 --- /dev/null +++ b/source4/lib/ldb/ldb_ildap/config.mk @@ -0,0 +1,14 @@ +################################################ +# Start MODULE ldb_ildap +[MODULE::ldb_ildap] +SUBSYSTEM = LIBLDB +CFLAGS = -Ilib/ldb/include +PRIVATE_DEPENDENCIES = LIBTALLOC LIBCLI_LDAP +INIT_FUNCTION = ldb_ildap_init +ALIASES = ldapi ldaps ldap +OBJ_FILES = \ + ldb_ildap.o +# End MODULE ldb_ildap +################################################ + + diff --git a/source4/lib/ldb/ldb_ildap/ldb_ildap.c b/source4/lib/ldb/ldb_ildap/ldb_ildap.c index 440686c65e..7b9023958c 100644 --- a/source4/lib/ldb/ldb_ildap/ldb_ildap.c +++ b/source4/lib/ldb/ldb_ildap/ldb_ildap.c @@ -646,7 +646,7 @@ static int ildb_rename(struct ldb_module *module, struct ldb_request *req) return LDB_ERR_INVALID_DN_SYNTAX; } - msg->r.ModifyDNRequest.deleteolddn = True; + msg->r.ModifyDNRequest.deleteolddn = true; return ildb_request_send(ildb, msg, req); } diff --git a/source4/lib/ldb/ldb_tdb/ldb_cache.c b/source4/lib/ldb/ldb_tdb/ldb_cache.c index 6bbf31dee7..de489e3d8b 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_cache.c +++ b/source4/lib/ldb/ldb_tdb/ldb_cache.c @@ -38,7 +38,6 @@ #define LTDB_FLAG_CASE_INSENSITIVE (1<<0) #define LTDB_FLAG_INTEGER (1<<1) #define LTDB_FLAG_HIDDEN (1<<2) -#define LTDB_FLAG_OBJECTCLASS (1<<3) /* valid attribute flags */ static const struct { @@ -58,7 +57,7 @@ static const struct { */ static void ltdb_attributes_unload(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data; struct ldb_message *msg; int i; @@ -105,7 +104,7 @@ static int ltdb_attributes_flags(struct ldb_message_element *el, unsigned *v) */ static int ltdb_attributes_load(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data; struct ldb_message *msg = ltdb->cache->attributes; struct ldb_dn *dn; int i, r; @@ -168,71 +167,11 @@ failed: /* - register any subclasses from @SUBCLASSES -*/ -static int ltdb_subclasses_load(struct ldb_module *module) -{ - struct ltdb_private *ltdb = module->private_data; - struct ldb_message *msg = ltdb->cache->subclasses; - struct ldb_dn *dn; - int i, j, r; - - dn = ldb_dn_new(module, module->ldb, LTDB_SUBCLASSES); - if (dn == NULL) goto failed; - - r = ltdb_search_dn1(module, dn, msg); - if (r != LDB_SUCCESS && r != LDB_ERR_NO_SUCH_OBJECT) { - talloc_free(dn); - goto failed; - } - talloc_free(dn); - - for (i=0;i<msg->num_elements;i++) { - struct ldb_message_element *el = &msg->elements[i]; - for (j=0;j<el->num_values;j++) { - if (ldb_subclass_add(module->ldb, el->name, - (char *)el->values[j].data) != 0) { - goto failed; - } - } - } - - return 0; -failed: - return -1; -} - - -/* - de-register any @SUBCLASSES -*/ -static void ltdb_subclasses_unload(struct ldb_module *module) -{ - struct ltdb_private *ltdb = module->private_data; - struct ldb_message *msg; - int i; - - if (ltdb->cache->subclasses == NULL) { - /* no previously loaded subclasses */ - return; - } - - msg = ltdb->cache->subclasses; - for (i=0;i<msg->num_elements;i++) { - ldb_subclass_remove(module->ldb, msg->elements[i].name); - } - - talloc_free(ltdb->cache->subclasses); - ltdb->cache->subclasses = NULL; -} - - -/* initialise the baseinfo record */ static int ltdb_baseinfo_init(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data; struct ldb_message *msg; struct ldb_message_element el; struct ldb_val val; @@ -285,7 +224,7 @@ failed: */ static void ltdb_cache_free(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data; ltdb->sequence_number = 0; talloc_free(ltdb->cache); @@ -298,7 +237,6 @@ static void ltdb_cache_free(struct ldb_module *module) int ltdb_cache_reload(struct ldb_module *module) { ltdb_attributes_unload(module); - ltdb_subclasses_unload(module); ltdb_cache_free(module); return ltdb_cache_load(module); } @@ -308,7 +246,7 @@ int ltdb_cache_reload(struct ldb_module *module) */ int ltdb_cache_load(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data; struct ldb_dn *baseinfo_dn = NULL; struct ldb_dn *indexlist_dn = NULL; uint64_t seq; @@ -325,10 +263,8 @@ int ltdb_cache_load(struct ldb_module *module) ltdb->cache = talloc_zero(ltdb, struct ltdb_cache); if (ltdb->cache == NULL) goto failed; ltdb->cache->indexlist = talloc_zero(ltdb->cache, struct ldb_message); - ltdb->cache->subclasses = talloc_zero(ltdb->cache, struct ldb_message); ltdb->cache->attributes = talloc_zero(ltdb->cache, struct ldb_message); if (ltdb->cache->indexlist == NULL || - ltdb->cache->subclasses == NULL || ltdb->cache->attributes == NULL) { goto failed; } @@ -369,16 +305,12 @@ int ltdb_cache_load(struct ldb_module *module) memset(<db->cache->last_attribute, 0, sizeof(ltdb->cache->last_attribute)); ltdb_attributes_unload(module); - ltdb_subclasses_unload(module); talloc_free(ltdb->cache->indexlist); - talloc_free(ltdb->cache->subclasses); ltdb->cache->indexlist = talloc_zero(ltdb->cache, struct ldb_message); - ltdb->cache->subclasses = talloc_zero(ltdb->cache, struct ldb_message); ltdb->cache->attributes = talloc_zero(ltdb->cache, struct ldb_message); if (ltdb->cache->indexlist == NULL || - ltdb->cache->subclasses == NULL || ltdb->cache->attributes == NULL) { goto failed; } @@ -394,9 +326,6 @@ int ltdb_cache_load(struct ldb_module *module) if (ltdb_attributes_load(module) == -1) { goto failed; } - if (ltdb_subclasses_load(module) == -1) { - goto failed; - } done: talloc_free(baseinfo); @@ -417,7 +346,7 @@ failed: */ int ltdb_increase_sequence_number(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data; struct ldb_message *msg; struct ldb_message_element el[2]; struct ldb_val val; diff --git a/source4/lib/ldb/ldb_tdb/ldb_index.c b/source4/lib/ldb/ldb_tdb/ldb_index.c index 1fe697f277..cf9380f8c0 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_index.c +++ b/source4/lib/ldb/ldb_tdb/ldb_index.c @@ -45,7 +45,7 @@ static int ldb_list_find(const void *needle, const void *base, size_t nmemb, size_t size, comparison_fn_t comp_fn) { - const char *base_p = base; + const char *base_p = (const char *)base; size_t min_i, max_i, test_i; if (nmemb == 0) { @@ -258,67 +258,6 @@ static int ltdb_index_dn_simple(struct ldb_module *module, static int list_union(struct ldb_context *, struct dn_list *, const struct dn_list *); /* - return a list of dn's that might match a simple indexed search on - the special objectclass attribute - */ -static int ltdb_index_dn_objectclass(struct ldb_module *module, - const struct ldb_parse_tree *tree, - const struct ldb_message *index_list, - struct dn_list *list) -{ - struct ldb_context *ldb = module->ldb; - unsigned int i; - int ret; - const char *target = (const char *)tree->u.equality.value.data; - const char **subclasses; - - list->count = 0; - list->dn = NULL; - - ret = ltdb_index_dn_simple(module, tree, index_list, list); - - subclasses = ldb_subclass_list(module->ldb, target); - - if (subclasses == NULL) { - return ret; - } - - for (i=0;subclasses[i];i++) { - struct ldb_parse_tree tree2; - struct dn_list *list2; - tree2.operation = LDB_OP_EQUALITY; - tree2.u.equality.attr = LTDB_OBJECTCLASS; - if (!tree2.u.equality.attr) { - return LDB_ERR_OPERATIONS_ERROR; - } - tree2.u.equality.value.data = - (uint8_t *)talloc_strdup(list, subclasses[i]); - if (tree2.u.equality.value.data == NULL) { - return LDB_ERR_OPERATIONS_ERROR; - } - tree2.u.equality.value.length = strlen(subclasses[i]); - list2 = talloc(list, struct dn_list); - if (list2 == NULL) { - talloc_free(tree2.u.equality.value.data); - return LDB_ERR_OPERATIONS_ERROR; - } - if (ltdb_index_dn_objectclass(module, &tree2, - index_list, list2) == LDB_SUCCESS) { - if (list->count == 0) { - *list = *list2; - ret = LDB_SUCCESS; - } else { - list_union(ldb, list, list2); - talloc_free(list2); - } - } - talloc_free(tree2.u.equality.value.data); - } - - return ret; -} - -/* return a list of dn's that might match a leaf indexed search */ static int ltdb_index_dn_leaf(struct ldb_module *module, @@ -326,9 +265,6 @@ static int ltdb_index_dn_leaf(struct ldb_module *module, const struct ldb_message *index_list, struct dn_list *list) { - if (ldb_attr_cmp(tree->u.equality.attr, LTDB_OBJECTCLASS) == 0) { - return ltdb_index_dn_objectclass(module, tree, index_list, list); - } if (ldb_attr_dn(tree->u.equality.attr) == 0) { list->dn = talloc_array(list, char *, 1); if (list->dn == NULL) { @@ -1014,7 +950,7 @@ static int ltdb_index_add1(struct ldb_module *module, const char *dn, static int ltdb_index_add0(struct ldb_module *module, const char *dn, struct ldb_message_element *elements, int num_el) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data; int ret; unsigned int i, j; @@ -1138,7 +1074,7 @@ int ltdb_index_del_value(struct ldb_module *module, const char *dn, */ int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data; int ret; const char *dn; unsigned int i, j; @@ -1180,7 +1116,7 @@ int ltdb_index_del(struct ldb_module *module, const struct ldb_message *msg) */ int ltdb_index_one(struct ldb_module *module, const struct ldb_message *msg, int add) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data; struct ldb_message_element el; struct ldb_val val; struct ldb_dn *pdn; @@ -1244,7 +1180,7 @@ static int delete_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, vo */ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void *state) { - struct ldb_module *module = state; + struct ldb_module *module = (struct ldb_module *)state; struct ldb_message *msg; const char *dn = NULL; int ret; @@ -1309,7 +1245,7 @@ static int re_index(struct tdb_context *tdb, TDB_DATA key, TDB_DATA data, void * */ int ltdb_reindex(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data; int ret; if (ltdb_cache_reload(module) != 0) { diff --git a/source4/lib/ldb/ldb_tdb/ldb_search.c b/source4/lib/ldb/ldb_tdb/ldb_search.c index 013b341d42..a195a39391 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_search.c +++ b/source4/lib/ldb/ldb_tdb/ldb_search.c @@ -210,7 +210,7 @@ static struct ldb_message *ltdb_pull_attrs(struct ldb_module *module, */ int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_message *msg) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data; int ret; TDB_DATA tdb_key, tdb_data; @@ -252,7 +252,7 @@ int ltdb_search_dn1(struct ldb_module *module, struct ldb_dn *dn, struct ldb_mes */ static int ltdb_lock_read(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data; return tdb_lockall_read(ltdb->tdb); } @@ -261,7 +261,7 @@ static int ltdb_lock_read(struct ldb_module *module) */ static int ltdb_unlock_read(struct ldb_module *module) { - struct ltdb_private *ltdb = module->private_data; + struct ltdb_private *ltdb = (struct ltdb_private *)module->private_data; return tdb_unlockall_read(ltdb->tdb); } diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.c b/source4/lib/ldb/ldb_tdb/ldb_tdb.c index 324a8e3881..3461f98d5f 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.c +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.c @@ -145,7 +145,7 @@ struct TDB_DATA ltdb_key(struct ldb_module *module, struct ldb_dn *dn) goto failed; } - key_str = talloc_append_string(ldb, key_str, dn_folded); + key_str = talloc_strdup_append_buffer(key_str, dn_folded); if (!key_str) { goto failed; } @@ -856,16 +856,38 @@ static int ltdb_rename(struct ldb_module *module, struct ldb_request *req) goto done; } - ret = ltdb_add_internal(module, msg); - if (ret != LDB_SUCCESS) { - goto done; - } + if (ldb_dn_compare(req->op.rename.olddn, req->op.rename.newdn) == 0) { + /* The rename operation is apparently only changing case - + the DNs are the same. Delete the old DN before adding + the new one to avoid a TDB_ERR_EXISTS error. - tret = ltdb_delete_internal(module, req->op.rename.olddn); - if (tret != LDB_SUCCESS) { - ltdb_delete_internal(module, req->op.rename.newdn); - ret = LDB_ERR_OPERATIONS_ERROR; - goto done; + The only drawback to this is that if the delete + succeeds but the add fails, we rely on the + transaction to roll this all back. */ + ret = ltdb_delete_internal(module, req->op.rename.olddn); + if (ret != LDB_SUCCESS) { + goto done; + } + + ret = ltdb_add_internal(module, msg); + if (ret != LDB_SUCCESS) { + goto done; + } + } else { + /* The rename operation is changing DNs. Try to add the new + DN first to avoid clobbering another DN not related to + this rename operation. */ + ret = ltdb_add_internal(module, msg); + if (ret != LDB_SUCCESS) { + goto done; + } + + tret = ltdb_delete_internal(module, req->op.rename.olddn); + if (tret != LDB_SUCCESS) { + ltdb_delete_internal(module, req->op.rename.newdn); + ret = LDB_ERR_OPERATIONS_ERROR; + goto done; + } } if (ltdb_ac->callback) { diff --git a/source4/lib/ldb/ldb_tdb/ldb_tdb.h b/source4/lib/ldb/ldb_tdb/ldb_tdb.h index 956f18688b..d4a8ff2fb1 100644 --- a/source4/lib/ldb/ldb_tdb/ldb_tdb.h +++ b/source4/lib/ldb/ldb_tdb/ldb_tdb.h @@ -1,11 +1,4 @@ - -#ifdef _SAMBA_BUILD_ -#include "system/filesys.h" -#endif - -#if (_SAMBA_BUILD_ >= 4) -#include "lib/tdb/include/tdb.h" -#elif defined(_SAMBA_BUILD_) +#if (_SAMBA_BUILD_ == 3) #include "tdb/include/tdb.h" #else #include "tdb.h" @@ -28,7 +21,6 @@ struct ltdb_private { struct ltdb_cache { struct ldb_message *indexlist; struct ldb_message *attributes; - struct ldb_message *subclasses; struct { char *name; @@ -63,7 +55,6 @@ struct ltdb_context { #define LTDB_IDXONE "@IDXONE" #define LTDB_BASEINFO "@BASEINFO" #define LTDB_ATTRIBUTES "@ATTRIBUTES" -#define LTDB_SUBCLASSES "@SUBCLASSES" /* special attribute types */ #define LTDB_SEQUENCE_NUMBER "sequenceNumber" diff --git a/source4/lib/ldb/modules/paged_searches.c b/source4/lib/ldb/modules/paged_searches.c index 3e0941357e..749858b49b 100644 --- a/source4/lib/ldb/modules/paged_searches.c +++ b/source4/lib/ldb/modules/paged_searches.c @@ -90,7 +90,10 @@ static struct ldb_handle *init_handle(void *mem_ctx, struct ldb_module *module, ac->up_context = context; ac->up_callback = callback; - ac->pending = False; + ac->pending = false; + + + ac->saved_referrals = NULL; ac->num_referrals = 0; @@ -110,7 +113,7 @@ static int check_ps_continuation(struct ldb_reply *ares, struct ps_context *ac) rep_control = talloc_get_type(ares->controls[0]->data, struct ldb_paged_control); if (rep_control->cookie_len == 0) { /* we are done */ - ac->pending = False; + ac->pending = false; return LDB_SUCCESS; } @@ -135,7 +138,7 @@ static int check_ps_continuation(struct ldb_reply *ares, struct ps_context *ac) rep_control->cookie_len); req_control->cookie_len = rep_control->cookie_len; - ac->pending = True; + ac->pending = true; return LDB_SUCCESS; } @@ -395,7 +398,7 @@ static int check_supported_paged(struct ldb_context *ldb, void *context, if (ldb_msg_check_string_attribute(ares->message, "supportedControl", LDB_CONTROL_PAGED_RESULTS_OID)) { - data->paged_supported = True; + data->paged_supported = true; } } return LDB_SUCCESS; @@ -415,7 +418,7 @@ static int ps_init(struct ldb_module *module) return LDB_ERR_OTHER; } module->private_data = data; - data->paged_supported = False; + data->paged_supported = false; req = talloc(module, struct ldb_request); if (req == NULL) { diff --git a/source4/lib/ldb/setup.py b/source4/lib/ldb/setup.py new file mode 100755 index 0000000000..e5fcddf0db --- /dev/null +++ b/source4/lib/ldb/setup.py @@ -0,0 +1,8 @@ +#!/usr/bin/python +from distutils.core import setup +from distutils.extension import Extension +setup(name='ldb', + version='1.0', + ext_modules=[Extension('_ldb', ['swig/ldb.i'], include_dirs=['include'], + libraries=['ldb','ldap'])], + ) diff --git a/source4/lib/ldb/swig/ldb.i b/source4/lib/ldb/swig/ldb.i index 6a0adb7bf8..cdf1d66de1 100644 --- a/source4/lib/ldb/swig/ldb.i +++ b/source4/lib/ldb/swig/ldb.i @@ -36,9 +36,9 @@ typedef long long int64_t; /* Include headers */ -#include "lib/replace/replace.h" -#include "lib/talloc/talloc.h" -#include "lib/ldb/include/ldb.h" +#include <stdbool.h> +#include "talloc.h" +#include "ldb.h" %} @@ -234,6 +234,8 @@ int ldb_msg_sanity_check(struct ldb_context *ldb, const struct ldb_message *msg) /* DN operations */ -struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn); +/* struct ldb_dn *ldb_dn_explode(void *mem_ctx, const char *dn); */ -char *ldb_dn_linearize(void *mem_ctx, const struct ldb_dn *dn); +/* char *ldb_dn_linearize(void *mem_ctx, const struct ldb_dn *dn); */ + +%rename(ldb_context) Ldb; diff --git a/source4/lib/ldb/tests/schema-tests/schema.ldif b/source4/lib/ldb/tests/schema-tests/schema.ldif index 515408144a..4ab1932839 100644 --- a/source4/lib/ldb/tests/schema-tests/schema.ldif +++ b/source4/lib/ldb/tests/schema-tests/schema.ldif @@ -26,18 +26,6 @@ lmPwdHistory: HIDDEN createTimestamp: HIDDEN modifyTimestamp: HIDDEN -dn: @SUBCLASSES -top: domain -top: person -top: group -domain: domainDNS -domain: builtinDomain -person: organizationalPerson -organizationalPerson: user -user: computer -template: userTemplate -template: groupTemplate - dn: @MODULES @LIST: timestamps,schema diff --git a/source4/lib/ldb/tests/test-tdb-features.sh b/source4/lib/ldb/tests/test-tdb-features.sh index 09a46d833e..fc0959c54a 100644 --- a/source4/lib/ldb/tests/test-tdb-features.sh +++ b/source4/lib/ldb/tests/test-tdb-features.sh @@ -83,16 +83,6 @@ echo "Testing class search" checkcount 0 '(objectClass=otherclass)' checkcount 1 '(objectClass=testclass)' -echo "Adding subclass" -cat <<EOF | $VALGRIND bin/ldbmodify || exit 1 -dn: @SUBCLASSES -changetype: add -add: otherclass -otherclass: testclass -EOF -checkcount 1 '(objectClass=otherclass)' -checkcount 1 '(objectClass=testclass)' - echo "Adding index" cat <<EOF | $VALGRIND bin/ldbadd || exit 1 dn: @INDEXLIST diff --git a/source4/lib/ldb/tools/ad2oLschema.c b/source4/lib/ldb/tools/ad2oLschema.c index 761339b96f..5fcf752578 100644 --- a/source4/lib/ldb/tools/ad2oLschema.c +++ b/source4/lib/ldb/tools/ad2oLschema.c @@ -36,6 +36,7 @@ #include "system/locale.h" #include "tools/cmdline.h" #include "tools/convert.h" +#include "param/param.h" struct schema_conv { int count; @@ -354,7 +355,7 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_ const char *description = ldb_msg_find_attr_as_string(msg, "description", NULL); const char *oid = ldb_msg_find_attr_as_string(msg, "attributeID", NULL); const char *syntax = ldb_msg_find_attr_as_string(msg, "attributeSyntax", NULL); - BOOL single_value = ldb_msg_find_attr_as_bool(msg, "isSingleValued", False); + bool single_value = ldb_msg_find_attr_as_bool(msg, "isSingleValued", false); const struct syntax_map *map = find_syntax_map_by_ad_oid(syntax); char *schema_entry = NULL; int j; @@ -676,7 +677,7 @@ static struct schema_conv process_convert(struct ldb_context *ldb, enum convert_ } } - target_str = lp_parm_string(-1, "convert", "target"); + target_str = lp_parm_string(global_loadparm, NULL, "convert", "target"); if (!target_str || strcasecmp(target_str, "openldap") == 0) { target = TARGET_OPENLDAP; diff --git a/source4/lib/ldb/tools/cmdline.c b/source4/lib/ldb/tools/cmdline.c index 08f5dc721f..2cf8212154 100644 --- a/source4/lib/ldb/tools/cmdline.c +++ b/source4/lib/ldb/tools/cmdline.c @@ -27,7 +27,7 @@ #if (_SAMBA_BUILD_ >= 4) #include "includes.h" #include "lib/cmdline/popt_common.h" -#include "lib/ldb/samba/ldif_handlers.h" +#include "lib/ldb-samba/ldif_handlers.h" #include "auth/gensec/gensec.h" #include "auth/auth.h" #include "db_wrap.h" diff --git a/source4/lib/ldb/tools/config.mk b/source4/lib/ldb/tools/config.mk new file mode 100644 index 0000000000..bf6c5f963c --- /dev/null +++ b/source4/lib/ldb/tools/config.mk @@ -0,0 +1,84 @@ +################################################ +# Start SUBSYSTEM LIBLDB_CMDLINE +[SUBSYSTEM::LIBLDB_CMDLINE] +CFLAGS = -Ilib/ldb -Ilib/ldb/include +OBJ_FILES= \ + cmdline.o +PUBLIC_DEPENDENCIES = LIBLDB LIBPOPT +PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL POPT_SAMBA POPT_CREDENTIALS gensec +# End SUBSYSTEM LIBLDB_CMDLINE +################################################ + +################################################ +# Start BINARY ldbadd +[BINARY::ldbadd] +INSTALLDIR = BINDIR +OBJ_FILES = \ + ldbadd.o +PRIVATE_DEPENDENCIES = \ + LIBLDB_CMDLINE LIBCLI_RESOLVE +MANPAGE = ../man/ldbadd.1 +# End BINARY ldbadd +################################################ + +################################################ +# Start BINARY ldbdel +[BINARY::ldbdel] +INSTALLDIR = BINDIR +OBJ_FILES= \ + ldbdel.o +PRIVATE_DEPENDENCIES = \ + LIBLDB_CMDLINE +MANPAGE = ../man/ldbdel.1 +# End BINARY ldbdel +################################################ + +################################################ +# Start BINARY ldbmodify +[BINARY::ldbmodify] +INSTALLDIR = BINDIR +OBJ_FILES= \ + ldbmodify.o +PRIVATE_DEPENDENCIES = \ + LIBLDB_CMDLINE +MANPAGE = ../man/ldbmodify.1 +# End BINARY ldbmodify +################################################ + +################################################ +# Start BINARY ldbsearch +[BINARY::ldbsearch] +INSTALLDIR = BINDIR +OBJ_FILES= \ + ldbsearch.o +PRIVATE_DEPENDENCIES = \ + LIBLDB_CMDLINE +MANPAGE = ../man/ldbsearch.1 +# End BINARY ldbsearch +################################################ + +################################################ +# Start BINARY ldbedit +[BINARY::ldbedit] +INSTALLDIR = BINDIR +OBJ_FILES= \ + ldbedit.o +PRIVATE_DEPENDENCIES = \ + LIBLDB_CMDLINE +MANPAGE = ../man/ldbedit.1 +# End BINARY ldbedit +################################################ + +################################################ +# Start BINARY ldbrename +[BINARY::ldbrename] +INSTALLDIR = BINDIR +OBJ_FILES= \ + ldbrename.o +PRIVATE_DEPENDENCIES = \ + LIBLDB_CMDLINE +MANPAGE = ../man/ldbrename.1 +# End BINARY ldbrename +################################################ + + diff --git a/source4/lib/messaging/irpc.h b/source4/lib/messaging/irpc.h index bcfc1f1ab4..989e5d4255 100644 --- a/source4/lib/messaging/irpc.h +++ b/source4/lib/messaging/irpc.h @@ -76,13 +76,12 @@ struct irpc_request { } async; }; +struct loadparm_context; + typedef void (*msg_callback_t)(struct messaging_context *msg, void *private, uint32_t msg_type, struct server_id server_id, DATA_BLOB *data); -struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, - struct server_id server_id, - struct event_context *ev); NTSTATUS messaging_send(struct messaging_context *msg, struct server_id server, uint32_t msg_type, DATA_BLOB *data); NTSTATUS messaging_register(struct messaging_context *msg, void *private, @@ -91,9 +90,11 @@ NTSTATUS messaging_register(struct messaging_context *msg, void *private, NTSTATUS messaging_register_tmp(struct messaging_context *msg, void *private, msg_callback_t fn, uint32_t *msg_type); struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, + const char *dir, struct server_id server_id, struct event_context *ev); struct messaging_context *messaging_client_init(TALLOC_CTX *mem_ctx, + const char *dir, struct event_context *ev); NTSTATUS messaging_send_ptr(struct messaging_context *msg, struct server_id server, uint32_t msg_type, void *ptr); diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c index c4c0d0e059..36cf9aa609 100644 --- a/source4/lib/messaging/messaging.c +++ b/source4/lib/messaging/messaging.c @@ -34,6 +34,7 @@ #include "lib/util/util_tdb.h" #include "lib/util/util_tdb.h" #include "cluster/cluster.h" +#include "param/param.h" /* change the message version with any incompatible changes in the protocol */ #define MESSAGING_VERSION 1 @@ -136,7 +137,8 @@ static void messaging_dispatch(struct messaging_context *msg, struct messaging_r /* temporary IDs use an idtree, the rest use a array of pointers */ if (rec->header->msg_type >= MSG_TMP_BASE) { - d = idr_find(msg->dispatch_tree, rec->header->msg_type); + d = (struct dispatch_fn *)idr_find(msg->dispatch_tree, + rec->header->msg_type); } else if (rec->header->msg_type < msg->num_types) { d = msg->dispatch[rec->header->msg_type]; } else { @@ -416,7 +418,8 @@ void messaging_deregister(struct messaging_context *msg, uint32_t msg_type, void struct dispatch_fn *d, *next; if (msg_type >= msg->num_types) { - d = idr_find(msg->dispatch_tree, msg_type); + d = (struct dispatch_fn *)idr_find(msg->dispatch_tree, + msg_type); if (!d) return; idr_remove(msg->dispatch_tree, msg_type); talloc_free(d); @@ -504,7 +507,7 @@ NTSTATUS messaging_send_ptr(struct messaging_context *msg, struct server_id serv { DATA_BLOB blob; - blob.data = (void *)&ptr; + blob.data = (uint8_t *)&ptr; blob.length = sizeof(void *); return messaging_send(msg, server, msg_type, &blob); @@ -527,13 +530,13 @@ static int messaging_destructor(struct messaging_context *msg) create the listening socket and setup the dispatcher */ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, + const char *dir, struct server_id server_id, struct event_context *ev) { struct messaging_context *msg; NTSTATUS status; struct socket_address *path; - char *dir; msg = talloc_zero(mem_ctx, struct messaging_context); if (msg == NULL) { @@ -552,11 +555,9 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, } /* create the messaging directory if needed */ - dir = smbd_tmp_path(msg, "messaging"); mkdir(dir, 0700); - talloc_free(dir); - msg->base_path = smbd_tmp_path(msg, "messaging"); + msg->base_path = talloc_reference(msg, dir); msg->path = messaging_path(msg, server_id); msg->server_id = server_id; msg->idr = idr_init(msg); @@ -607,12 +608,13 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, A hack, for the short term until we get 'client only' messaging in place */ struct messaging_context *messaging_client_init(TALLOC_CTX *mem_ctx, + const char *dir, struct event_context *ev) { struct server_id id; ZERO_STRUCT(id); id.id = random() % 0x10000000; - return messaging_init(mem_ctx, id, ev); + return messaging_init(mem_ctx, dir, id, ev); } /* a list of registered irpc server functions @@ -665,7 +667,7 @@ static void irpc_handler_reply(struct messaging_context *msg_ctx, struct irpc_me { struct irpc_request *irpc; - irpc = idr_find(msg_ctx->idr, m->header.callid); + irpc = (struct irpc_request *)idr_find(msg_ctx->idr, m->header.callid); if (irpc == NULL) return; /* parse the reply data */ diff --git a/source4/lib/policy/lex.c b/source4/lib/policy/lex.c index d599c92915..fd4c102142 100644 --- a/source4/lib/policy/lex.c +++ b/source4/lib/policy/lex.c @@ -909,7 +909,7 @@ YY_RULE_SETUP case 13: YY_RULE_SETUP #line 61 "lex.l" -{ return MACHINE; } +{ return CLASS_MACHINE; } YY_BREAK case 14: YY_RULE_SETUP @@ -964,7 +964,7 @@ YY_RULE_SETUP case 24: YY_RULE_SETUP #line 72 "lex.l" -{ return USER; } +{ return CLASS_USER; } YY_BREAK case 25: YY_RULE_SETUP diff --git a/source4/lib/policy/lex.l b/source4/lib/policy/lex.l index 1157bca2f7..199cd228c0 100644 --- a/source4/lib/policy/lex.l +++ b/source4/lib/policy/lex.l @@ -58,7 +58,7 @@ END { return END; } EXPLAIN { return EXPLAIN; } ITEMLIST { return ITEMLIST; } KEYNAME { return KEYNAME; } -MACHINE { return MACHINE; } +MACHINE { return CLASS_MACHINE; } MIN { return MINIMUM; } MAX { return MAXIMUM; } NAME { return NAME; } @@ -69,7 +69,7 @@ REQUIRED { return REQUIRED; } SPIN { return SPIN; } SUPPORTED { return SUPPORTED; } TEXT { return TEXT; } -USER { return USER; } +USER { return CLASS_USER; } VALUE { return VALUE; } VALUENAME { return VALUENAME; } VALUEON { return VALUEON; } diff --git a/source4/lib/policy/parse_adm.c b/source4/lib/policy/parse_adm.c index 91cda1b262..c68e2db814 100644 --- a/source4/lib/policy/parse_adm.c +++ b/source4/lib/policy/parse_adm.c @@ -68,8 +68,8 @@ enum yytokentype { CATEGORY = 258, CLASS = 259, - USER = 260, - MACHINE = 261, + CLASS_USER = 260, + CLASS_MACHINE = 261, POLICY = 262, KEYNAME = 263, EXPLAIN = 264, @@ -106,8 +106,8 @@ /* Tokens. */ #define CATEGORY 258 #define CLASS 259 -#define USER 260 -#define MACHINE 261 +#define CLASS_USER 260 +#define CLASS_MACHINE 261 #define POLICY 262 #define KEYNAME 263 #define EXPLAIN 264 @@ -520,19 +520,19 @@ static const yytype_uint8 yyrline[] = First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$end", "error", "$undefined", "CATEGORY", "CLASS", "USER", "MACHINE", - "POLICY", "KEYNAME", "EXPLAIN", "VALUENAME", "VALUEON", "VALUEOFF", - "PART", "ITEMLIST", "NAME", "VALUE", "NUMERIC", "EDITTEXT", "TEXT", - "DROPDOWNLIST", "CHECKBOX", "MINIMUM", "MAXIMUM", "DEFAULT", "END", - "ACTIONLIST", "DEL", "SUPPORTED", "LITERAL", "INTEGER", "LOOKUPLITERAL", - "CLIENTEXT", "REQUIRED", "NOSORT", "SPIN", "EQUALS", "STRINGSSECTION", - "$accept", "admfile", "classes", "class", "classvalue", "categories", - "string", "category", "categoryitem", "categoryitems", "policy", - "policyitem", "policyitems", "valuetype", "part", "spin", "partitem", - "partitems", "min", "max", "defaultvalue", "explain", "value", "valueon", - "valueoff", "valuename", "keyname", "itemlist", "itemname", "itemvalue", - "item", "items", "supported", "actionlist", "actions", "variable", - "variables", "strings", 0 + "$end", "error", "$undefined", "CATEGORY", "CLASS", "CLASS_USER", + "CLASS_MACHINE", "POLICY", "KEYNAME", "EXPLAIN", "VALUENAME", "VALUEON", + "VALUEOFF", "PART", "ITEMLIST", "NAME", "VALUE", "NUMERIC", "EDITTEXT", + "TEXT", "DROPDOWNLIST", "CHECKBOX", "MINIMUM", "MAXIMUM", "DEFAULT", + "END", "ACTIONLIST", "DEL", "SUPPORTED", "LITERAL", "INTEGER", + "LOOKUPLITERAL", "CLIENTEXT", "REQUIRED", "NOSORT", "SPIN", "EQUALS", + "STRINGSSECTION", "$accept", "admfile", "classes", "class", "classvalue", + "categories", "string", "category", "categoryitem", "categoryitems", + "policy", "policyitem", "policyitems", "valuetype", "part", "spin", + "partitem", "partitems", "min", "max", "defaultvalue", "explain", + "value", "valueon", "valueoff", "valuename", "keyname", "itemlist", + "itemname", "itemvalue", "item", "items", "supported", "actionlist", + "actions", "variable", "variables", "strings", 0 }; #endif diff --git a/source4/lib/policy/parse_adm.h b/source4/lib/policy/parse_adm.h index ba134db19d..372e4b9680 100644 --- a/source4/lib/policy/parse_adm.h +++ b/source4/lib/policy/parse_adm.h @@ -41,8 +41,8 @@ enum yytokentype { CATEGORY = 258, CLASS = 259, - USER = 260, - MACHINE = 261, + CLASS_USER = 260, + CLASS_MACHINE = 261, POLICY = 262, KEYNAME = 263, EXPLAIN = 264, @@ -79,8 +79,8 @@ /* Tokens. */ #define CATEGORY 258 #define CLASS 259 -#define USER 260 -#define MACHINE 261 +#define CLASS_USER 260 +#define CLASS_MACHINE 261 #define POLICY 262 #define KEYNAME 263 #define EXPLAIN 264 diff --git a/source4/lib/policy/parse_adm.y b/source4/lib/policy/parse_adm.y index 450625f58a..1dc21cf1d3 100644 --- a/source4/lib/policy/parse_adm.y +++ b/source4/lib/policy/parse_adm.y @@ -37,8 +37,8 @@ extern int yylex (void); %token CATEGORY %token CLASS -%token USER -%token MACHINE +%token CLASS_USER +%token CLASS_MACHINE %token POLICY %token KEYNAME %token EXPLAIN @@ -73,7 +73,7 @@ admfile: classes strings; classes: /* empty */ | class classes; class: CLASS classvalue categories; -classvalue: USER|MACHINE; +classvalue: CLASS_USER|CLASS_MACHINE; categories: /* empty */ | category categories; diff --git a/source4/lib/registry/dir.c b/source4/lib/registry/dir.c index 146c5197fd..532770bcaf 100644 --- a/source4/lib/registry/dir.c +++ b/source4/lib/registry/dir.c @@ -1,18 +1,18 @@ -/* +/* Unix SMB/CIFS implementation. Registry interface - Copyright (C) Jelmer Vernooij 2004-2007. - + Copyright (C) Jelmer Vernooij 2004-2007. + 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -29,11 +29,11 @@ struct dir_key { static struct hive_operations reg_backend_dir; -static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx, - const struct hive_key *parent, - const char *name, const char *classname, - struct security_descriptor *desc, - struct hive_key **result) +static WERROR reg_dir_add_key(TALLOC_CTX *mem_ctx, + const struct hive_key *parent, + const char *name, const char *classname, + struct security_descriptor *desc, + struct hive_key **result) { struct dir_key *dk = talloc_get_type(parent, struct dir_key); char *path; @@ -61,8 +61,8 @@ static WERROR reg_dir_del_key(const struct hive_key *k, const char *name) char *child = talloc_asprintf(NULL, "%s/%s", dk->path, name); WERROR ret; - if (rmdir(child) == 0) - ret = WERR_OK; + if (rmdir(child) == 0) + ret = WERR_OK; else if (errno == ENOENT) ret = WERR_NOT_FOUND; else @@ -73,25 +73,26 @@ static WERROR reg_dir_del_key(const struct hive_key *k, const char *name) return ret; } -static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, - const struct hive_key *parent, - const char *name, struct hive_key **subkey) +static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, + const struct hive_key *parent, + const char *name, struct hive_key **subkey) { DIR *d; char *fullpath; const struct dir_key *p = talloc_get_type(parent, struct dir_key); struct dir_key *ret; - + if (name == NULL) { DEBUG(0, ("NULL pointer passed as directory name!")); return WERR_INVALID_PARAM; } - + fullpath = talloc_asprintf(mem_ctx, "%s/%s", p->path, name); - + d = opendir(fullpath); if (d == NULL) { - DEBUG(3,("Unable to open '%s': %s\n", fullpath, strerror(errno))); + DEBUG(3,("Unable to open '%s': %s\n", fullpath, + strerror(errno))); return WERR_BADFILE; } closedir(d); @@ -102,11 +103,11 @@ static WERROR reg_dir_open_key(TALLOC_CTX *mem_ctx, return WERR_OK; } -static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, - const struct hive_key *k, uint32_t idx, - const char **name, - const char **classname, - NTTIME *last_mod_time) +static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, + const struct hive_key *k, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time) { struct dirent *e; const struct dir_key *dk = talloc_get_type(k, struct dir_key); @@ -115,14 +116,14 @@ static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, d = opendir(dk->path); - if (d == NULL) + if (d == NULL) return WERR_INVALID_PARAM; - + while((e = readdir(d))) { if(!ISDOT(e->d_name) && !ISDOTDOT(e->d_name)) { struct stat stbuf; char *thispath; - + /* Check if file is a directory */ asprintf(&thispath, "%s/%s", dk->path, e->d_name); stat(thispath, &stbuf); @@ -153,12 +154,12 @@ static WERROR reg_dir_key_by_index(TALLOC_CTX *mem_ctx, return WERR_NO_MORE_ITEMS; } -WERROR reg_open_directory(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key) +WERROR reg_open_directory(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key) { struct dir_key *dk; - if (location == NULL) + if (location == NULL) return WERR_INVALID_PARAM; dk = talloc(parent_ctx, struct dir_key); @@ -168,8 +169,8 @@ WERROR reg_open_directory(TALLOC_CTX *parent_ctx, return WERR_OK; } -WERROR reg_create_directory(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key) +WERROR reg_create_directory(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key) { if (mkdir(location, 0700) != 0) { *key = NULL; @@ -179,11 +180,11 @@ WERROR reg_create_directory(TALLOC_CTX *parent_ctx, return reg_open_directory(parent_ctx, location, key); } -static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key, - const char **classname, - uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *lastmod) +static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *lastmod) { DIR *d; const struct dir_key *dk = talloc_get_type(key, struct dir_key); @@ -196,7 +197,7 @@ static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key, *classname = NULL; d = opendir(dk->path); - if (d == NULL) + if (d == NULL) return WERR_INVALID_PARAM; if (num_subkeys != NULL) @@ -207,10 +208,12 @@ static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key, while((e = readdir(d))) { if(!ISDOT(e->d_name) && !ISDOTDOT(e->d_name)) { - char *path = talloc_asprintf(ctx, "%s/%s", dk->path, e->d_name); + char *path = talloc_asprintf(ctx, "%s/%s", + dk->path, e->d_name); if (stat(path, &st) < 0) { - DEBUG(0, ("Error statting %s: %s\n", path, strerror(errno))); + DEBUG(0, ("Error statting %s: %s\n", path, + strerror(errno))); continue; } @@ -231,8 +234,8 @@ static WERROR reg_dir_get_info(TALLOC_CTX *ctx, const struct hive_key *key, return WERR_OK; } -static WERROR reg_dir_set_value (struct hive_key *key, const char *name, - uint32_t type, const DATA_BLOB data) +static WERROR reg_dir_set_value(struct hive_key *key, const char *name, + uint32_t type, const DATA_BLOB data) { const struct dir_key *dk = talloc_get_type(key, struct dir_key); char *path = talloc_asprintf(dk, "%s/%s", dk->path, name); @@ -245,9 +248,9 @@ static WERROR reg_dir_set_value (struct hive_key *key, const char *name, return WERR_OK; } -static WERROR reg_dir_get_value (TALLOC_CTX *mem_ctx, - struct hive_key *key, const char *name, - uint32_t *type, DATA_BLOB *data) +static WERROR reg_dir_get_value(TALLOC_CTX *mem_ctx, + struct hive_key *key, const char *name, + uint32_t *type, DATA_BLOB *data) { const struct dir_key *dk = talloc_get_type(key, struct dir_key); char *path = talloc_asprintf(mem_ctx, "%s/%s", dk->path, name); @@ -256,7 +259,7 @@ static WERROR reg_dir_get_value (TALLOC_CTX *mem_ctx, contents = file_load(path, &size, mem_ctx); talloc_free(path); - if (contents == NULL) + if (contents == NULL) return WERR_NOT_FOUND; if (type != NULL) @@ -267,11 +270,11 @@ static WERROR reg_dir_get_value (TALLOC_CTX *mem_ctx, return WERR_OK; } - -static WERROR reg_dir_enum_value (TALLOC_CTX *mem_ctx, - const struct hive_key *key, int idx, - const char **name, - uint32_t *type, DATA_BLOB *data) + +static WERROR reg_dir_enum_value(TALLOC_CTX *mem_ctx, + const struct hive_key *key, int idx, + const char **name, + uint32_t *type, DATA_BLOB *data) { const struct dir_key *dk = talloc_get_type(key, struct dir_key); DIR *d; @@ -280,19 +283,22 @@ static WERROR reg_dir_enum_value (TALLOC_CTX *mem_ctx, d = opendir(dk->path); if (d == NULL) { - DEBUG(3,("Unable to open '%s': %s\n", dk->path, strerror(errno))); + DEBUG(3,("Unable to open '%s': %s\n", dk->path, + strerror(errno))); return WERR_BADFILE; } i = 0; while((e = readdir(d))) { - if (ISDOT(e->d_name) || ISDOTDOT(e->d_name)) + if (ISDOT(e->d_name) || ISDOTDOT(e->d_name)) continue; if (i == idx) { if (name != NULL) *name = talloc_strdup(mem_ctx, e->d_name); - W_ERROR_NOT_OK_RETURN(reg_dir_get_value(mem_ctx, key, *name, type, data)); + W_ERROR_NOT_OK_RETURN(reg_dir_get_value(mem_ctx, key, + *name, type, + data)); return WERR_OK; } @@ -315,7 +321,7 @@ static WERROR reg_dir_del_value (struct hive_key *key, const char *name) return WERR_GENERAL_FAILURE; } talloc_free(path); - + return WERR_OK; } diff --git a/source4/lib/registry/hive.c b/source4/lib/registry/hive.c index 97ce883e66..16534aac9c 100644 --- a/source4/lib/registry/hive.c +++ b/source4/lib/registry/hive.c @@ -1,19 +1,19 @@ -/* +/* Unix SMB/CIFS implementation. Registry hive interface - Copyright (C) Jelmer Vernooij 2003-2007. - + Copyright (C) Jelmer Vernooij 2003-2007. + 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. @@ -24,10 +24,10 @@ #include "system/filesys.h" /** Open a registry file/host/etc */ -_PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - struct hive_key **root) +_PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct hive_key **root) { int fd, num; char peek[20]; @@ -54,28 +54,33 @@ _PUBLIC_ WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, return reg_open_regf_file(parent_ctx, location, root); } else if (!strncmp(peek, "TDB file", 8)) { close(fd); - return reg_open_ldb_file(parent_ctx, location, session_info, credentials, root); + return reg_open_ldb_file(parent_ctx, location, session_info, + credentials, root); } return WERR_BADFILE; } -_PUBLIC_ WERROR hive_key_get_info(TALLOC_CTX *mem_ctx, const struct hive_key *key, - const char **classname, uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time) +_PUBLIC_ WERROR hive_key_get_info(TALLOC_CTX *mem_ctx, + const struct hive_key *key, + const char **classname, uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time) { - return key->ops->get_key_info(mem_ctx, key, classname, num_subkeys, - num_values, last_change_time); + return key->ops->get_key_info(mem_ctx, key, classname, num_subkeys, + num_values, last_change_time); } -_PUBLIC_ WERROR hive_key_add_name(TALLOC_CTX *ctx, const struct hive_key *parent_key, - const char *name, const char *classname, struct security_descriptor *desc, - struct hive_key **key) +_PUBLIC_ WERROR hive_key_add_name(TALLOC_CTX *ctx, + const struct hive_key *parent_key, + const char *name, const char *classname, + struct security_descriptor *desc, + struct hive_key **key) { SMB_ASSERT(strchr(name, '\\') == NULL); - return parent_key->ops->add_key(ctx, parent_key, name, classname, desc, key); + return parent_key->ops->add_key(ctx, parent_key, name, classname, + desc, key); } _PUBLIC_ WERROR hive_key_del(const struct hive_key *key, const char *name) @@ -84,20 +89,21 @@ _PUBLIC_ WERROR hive_key_del(const struct hive_key *key, const char *name) } _PUBLIC_ WERROR hive_get_key_by_name(TALLOC_CTX *mem_ctx, - const struct hive_key *key, const char *name, - struct hive_key **subkey) + const struct hive_key *key, + const char *name, + struct hive_key **subkey) { return key->ops->get_key_by_name(mem_ctx, key, name, subkey); } WERROR hive_enum_key(TALLOC_CTX *mem_ctx, - const struct hive_key *key, uint32_t idx, - const char **name, - const char **classname, - NTTIME *last_mod_time) + const struct hive_key *key, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time) { - return key->ops->enum_key(mem_ctx, key, idx, name, classname, - last_mod_time); + return key->ops->enum_key(mem_ctx, key, idx, name, classname, + last_mod_time); } WERROR hive_set_value(struct hive_key *key, const char *name, uint32_t type, @@ -109,9 +115,9 @@ WERROR hive_set_value(struct hive_key *key, const char *name, uint32_t type, return key->ops->set_value(key, name, type, data); } -WERROR hive_get_value (TALLOC_CTX *mem_ctx, - struct hive_key *key, const char *name, - uint32_t *type, DATA_BLOB *data) +WERROR hive_get_value(TALLOC_CTX *mem_ctx, + struct hive_key *key, const char *name, + uint32_t *type, DATA_BLOB *data) { if (key->ops->get_value_by_name == NULL) return WERR_NOT_SUPPORTED; @@ -119,9 +125,10 @@ WERROR hive_get_value (TALLOC_CTX *mem_ctx, return key->ops->get_value_by_name(mem_ctx, key, name, type, data); } -WERROR hive_get_value_by_index (TALLOC_CTX *mem_ctx, - struct hive_key *key, uint32_t idx, const char **name, - uint32_t *type, DATA_BLOB *data) +WERROR hive_get_value_by_index(TALLOC_CTX *mem_ctx, + struct hive_key *key, uint32_t idx, + const char **name, + uint32_t *type, DATA_BLOB *data) { if (key->ops->enum_value == NULL) return WERR_NOT_SUPPORTED; @@ -130,7 +137,7 @@ WERROR hive_get_value_by_index (TALLOC_CTX *mem_ctx, } -WERROR hive_del_value (struct hive_key *key, const char *name) +WERROR hive_del_value(struct hive_key *key, const char *name) { if (key->ops->delete_value == NULL) return WERR_NOT_SUPPORTED; diff --git a/source4/lib/registry/hive.h b/source4/lib/registry/hive.h index 36491f149b..2f783dd15d 100644 --- a/source4/lib/registry/hive.h +++ b/source4/lib/registry/hive.h @@ -1,18 +1,18 @@ -/* +/* Unix SMB/CIFS implementation. Registry hive interface Copyright (C) Jelmer Vernooij 2003-2007. - + 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. @@ -23,15 +23,16 @@ #include <talloc.h> #include "librpc/gen_ndr/security.h" +#include "libcli/util/ntstatus.h" /** - * This file contains the hive API. This API is generally used for - * reading a specific file that contains just one hive. + * This file contains the hive API. This API is generally used for + * reading a specific file that contains just one hive. * * Good examples are .DAT (NTUSER.DAT) files. * - * This API does not have any notification support (that - * should be provided by the registry implementation), nor + * This API does not have any notification support (that + * should be provided by the registry implementation), nor * does it understand what predefined keys are. */ @@ -40,31 +41,32 @@ struct hive_key { }; struct hive_operations { - const char *name; + const char *name; /** * Open a specific subkey */ WERROR (*enum_key) (TALLOC_CTX *mem_ctx, - const struct hive_key *key, uint32_t idx, - const char **name, - const char **classname, - NTTIME *last_mod_time); + const struct hive_key *key, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time); /** * Open a subkey by name */ WERROR (*get_key_by_name) (TALLOC_CTX *mem_ctx, - const struct hive_key *key, const char *name, - struct hive_key **subkey); - + const struct hive_key *key, const char *name, + struct hive_key **subkey); + /** * Add a new key. */ WERROR (*add_key) (TALLOC_CTX *ctx, - const struct hive_key *parent_key, const char *name, - const char *classname, struct security_descriptor *desc, - struct hive_key **key); + const struct hive_key *parent_key, const char *name, + const char *classname, + struct security_descriptor *desc, + struct hive_key **key); /** * Remove an existing key. */ @@ -79,22 +81,22 @@ struct hive_operations { * Retrieve a registry value with a specific index. */ WERROR (*enum_value) (TALLOC_CTX *mem_ctx, - const struct hive_key *key, int idx, - const char **name, uint32_t *type, - DATA_BLOB *data); + const struct hive_key *key, int idx, + const char **name, uint32_t *type, + DATA_BLOB *data); /** * Retrieve a registry value with the specified name */ - WERROR (*get_value_by_name) (TALLOC_CTX *mem_ctx, - struct hive_key *key, const char *name, - uint32_t *type, DATA_BLOB *data); - + WERROR (*get_value_by_name) (TALLOC_CTX *mem_ctx, + struct hive_key *key, const char *name, + uint32_t *type, DATA_BLOB *data); + /** * Set a value on the specified registry key. */ - WERROR (*set_value) (struct hive_key *key, const char *name, - uint32_t type, const DATA_BLOB data); + WERROR (*set_value) (struct hive_key *key, const char *name, + uint32_t type, const DATA_BLOB data); /** * Remove a value. @@ -106,91 +108,93 @@ struct hive_operations { /** * Change the security descriptor on a registry key. * - * This should return WERR_NOT_SUPPORTED if the underlying - * format does not have a mechanism for storing + * This should return WERR_NOT_SUPPORTED if the underlying + * format does not have a mechanism for storing * security descriptors. */ - WERROR (*set_sec_desc) (struct hive_key *key, - const struct security_descriptor *desc); + WERROR (*set_sec_desc) (struct hive_key *key, + const struct security_descriptor *desc); /** * Retrieve the security descriptor on a registry key. * - * This should return WERR_NOT_SUPPORTED if the underlying - * format does not have a mechanism for storing + * This should return WERR_NOT_SUPPORTED if the underlying + * format does not have a mechanism for storing * security descriptors. */ WERROR (*get_sec_desc) (TALLOC_CTX *ctx, - const struct hive_key *key, - struct security_descriptor **desc); - + const struct hive_key *key, + struct security_descriptor **desc); + /** * Retrieve general information about a key. */ WERROR (*get_key_info) (TALLOC_CTX *mem_ctx, - const struct hive_key *key, - const char **classname, - uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time); + const struct hive_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time); }; struct cli_credentials; struct auth_session_info; -WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - struct hive_key **root); +WERROR reg_open_hive(TALLOC_CTX *parent_ctx, const char *location, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct hive_key **root); WERROR hive_key_get_info(TALLOC_CTX *mem_ctx, const struct hive_key *key, - const char **classname, uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time); + const char **classname, uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time); WERROR hive_key_add_name(TALLOC_CTX *ctx, const struct hive_key *parent_key, - const char *name, const char *classname, struct security_descriptor *desc, - struct hive_key **key); + const char *name, const char *classname, + struct security_descriptor *desc, + struct hive_key **key); WERROR hive_key_del(const struct hive_key *key, const char *name); WERROR hive_get_key_by_name(TALLOC_CTX *mem_ctx, - const struct hive_key *key, const char *name, - struct hive_key **subkey); + const struct hive_key *key, const char *name, + struct hive_key **subkey); WERROR hive_enum_key(TALLOC_CTX *mem_ctx, - const struct hive_key *key, uint32_t idx, - const char **name, - const char **classname, - NTTIME *last_mod_time); + const struct hive_key *key, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time); -WERROR hive_set_value (struct hive_key *key, const char *name, - uint32_t type, const DATA_BLOB data); +WERROR hive_set_value(struct hive_key *key, const char *name, + uint32_t type, const DATA_BLOB data); -WERROR hive_get_value (TALLOC_CTX *mem_ctx, - struct hive_key *key, const char *name, - uint32_t *type, DATA_BLOB *data); -WERROR hive_get_value_by_index (TALLOC_CTX *mem_ctx, - struct hive_key *key, uint32_t idx, const char **name, - uint32_t *type, DATA_BLOB *data); +WERROR hive_get_value(TALLOC_CTX *mem_ctx, + struct hive_key *key, const char *name, + uint32_t *type, DATA_BLOB *data); +WERROR hive_get_value_by_index(TALLOC_CTX *mem_ctx, + struct hive_key *key, uint32_t idx, + const char **name, + uint32_t *type, DATA_BLOB *data); -WERROR hive_del_value (struct hive_key *key, const char *name); +WERROR hive_del_value(struct hive_key *key, const char *name); WERROR hive_key_flush(struct hive_key *key); /* Individual backends */ -WERROR reg_open_directory(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key); -WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key); -WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - struct hive_key **k); - - -WERROR reg_create_directory(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key); -WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, - const char *location, - int major_version, - struct hive_key **key); +WERROR reg_open_directory(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key); +WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key); +WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct hive_key **k); + + +WERROR reg_create_directory(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key); +WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, + const char *location, + int major_version, + struct hive_key **key); #endif /* __REGISTRY_HIVE_H__ */ diff --git a/source4/lib/registry/interface.c b/source4/lib/registry/interface.c index 4950e1dacd..8f60a55ae9 100644 --- a/source4/lib/registry/interface.c +++ b/source4/lib/registry/interface.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. Transparent registry backend handling Copyright (C) Jelmer Vernooij 2003-2007. @@ -47,7 +47,7 @@ _PUBLIC_ const char *reg_get_predef_name(uint32_t hkey) { int i; for (i = 0; reg_predefined_keys[i].name; i++) { - if (reg_predefined_keys[i].handle == hkey) + if (reg_predefined_keys[i].handle == hkey) return reg_predefined_keys[i].name; } @@ -55,40 +55,42 @@ _PUBLIC_ const char *reg_get_predef_name(uint32_t hkey) } /** Get predefined key by name. */ -_PUBLIC_ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, - const char *name, - struct registry_key **key) +_PUBLIC_ WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, + const char *name, + struct registry_key **key) { int i; - + for (i = 0; reg_predefined_keys[i].name; i++) { - if (!strcasecmp(reg_predefined_keys[i].name, name)) - return reg_get_predefined_key(ctx, reg_predefined_keys[i].handle, - key); + if (!strcasecmp(reg_predefined_keys[i].name, name)) + return reg_get_predefined_key(ctx, + reg_predefined_keys[i].handle, + key); } DEBUG(1, ("No predefined key with name '%s'\n", name)); - + return WERR_BADFILE; } /** Get predefined key by id. */ -_PUBLIC_ WERROR reg_get_predefined_key(const struct registry_context *ctx, - uint32_t hkey, struct registry_key **key) +_PUBLIC_ WERROR reg_get_predefined_key(const struct registry_context *ctx, + uint32_t hkey, struct registry_key **key) { return ctx->ops->get_predefined_key(ctx, hkey, key); } /** - * Open a key + * Open a key * First tries to use the open_key function from the backend - * then falls back to get_subkey_by_name and later get_subkey_by_index + * then falls back to get_subkey_by_name and later get_subkey_by_index */ -_PUBLIC_ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, - const char *name, struct registry_key **result) +_PUBLIC_ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, + const char *name, struct registry_key **result) { if (parent == NULL) { - DEBUG(0, ("Invalid parent key specified for open of '%s'\n", name)); + DEBUG(0, ("Invalid parent key specified for open of '%s'\n", + name)); return WERR_INVALID_PARAM; } @@ -103,71 +105,71 @@ _PUBLIC_ WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, /** * Get value by index */ -_PUBLIC_ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - uint32_t idx, - const char **name, - uint32_t *type, - DATA_BLOB *data) +_PUBLIC_ WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + uint32_t idx, const char **name, + uint32_t *type, DATA_BLOB *data) { - if (key == NULL) + if (key == NULL) return WERR_INVALID_PARAM; if (key->context->ops->enum_value == NULL) return WERR_NOT_SUPPORTED; - return key->context->ops->enum_value(mem_ctx, key, idx, name, type, - data); + return key->context->ops->enum_value(mem_ctx, key, idx, name, + type, data); } -/** +/** * Get the number of subkeys. */ -_PUBLIC_ WERROR reg_key_get_info(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char **classname, - uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time) +_PUBLIC_ WERROR reg_key_get_info(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time) { - if (key == NULL) + if (key == NULL) return WERR_INVALID_PARAM; - + if (key->context->ops->get_key_info == NULL) return WERR_NOT_SUPPORTED; return key->context->ops->get_key_info(mem_ctx, - key, classname, num_subkeys, - num_values, last_change_time); + key, classname, num_subkeys, + num_values, last_change_time); } /** * Get subkey by index. */ -_PUBLIC_ WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, - const struct registry_key *key, int idx, const char **name, - const char **keyclass, NTTIME *last_changed_time) +_PUBLIC_ WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + int idx, const char **name, + const char **keyclass, + NTTIME *last_changed_time) { - if (key == NULL) + if (key == NULL) return WERR_INVALID_PARAM; if (key->context->ops->enum_key == NULL) return WERR_NOT_SUPPORTED; return key->context->ops->enum_key(mem_ctx, key, idx, name, - keyclass, last_changed_time); + keyclass, last_changed_time); } /** * Get value by name. */ -_PUBLIC_ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char *name, - uint32_t *type, - DATA_BLOB *data) +_PUBLIC_ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char *name, + uint32_t *type, + DATA_BLOB *data) { - if (key == NULL) + if (key == NULL) return WERR_INVALID_PARAM; if (key->context->ops->get_value == NULL) @@ -181,49 +183,49 @@ _PUBLIC_ WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, */ _PUBLIC_ WERROR reg_key_del(struct registry_key *parent, const char *name) { - if (parent == NULL) + if (parent == NULL) return WERR_INVALID_PARAM; - + if (parent->context->ops->delete_key == NULL) return WERR_NOT_SUPPORTED; - + return parent->context->ops->delete_key(parent, name); } /** * Add a key. */ -_PUBLIC_ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, - struct registry_key *parent, - const char *name, const char *key_class, - struct security_descriptor *desc, - struct registry_key **newkey) +_PUBLIC_ WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, + struct registry_key *parent, + const char *name, const char *key_class, + struct security_descriptor *desc, + struct registry_key **newkey) { - if (parent == NULL) + if (parent == NULL) return WERR_INVALID_PARAM; - + if (parent->context->ops->create_key == NULL) { - DEBUG(1, ("Backend '%s' doesn't support method add_key\n", + DEBUG(1, ("Backend '%s' doesn't support method add_key\n", parent->context->ops->name)); return WERR_NOT_SUPPORTED; } - return parent->context->ops->create_key(mem_ctx, parent, name, - key_class, desc, newkey); + return parent->context->ops->create_key(mem_ctx, parent, name, + key_class, desc, newkey); } /** * Set a value. */ -_PUBLIC_ WERROR reg_val_set(struct registry_key *key, const char *value, - uint32_t type, const DATA_BLOB data) +_PUBLIC_ WERROR reg_val_set(struct registry_key *key, const char *value, + uint32_t type, const DATA_BLOB data) { if (key == NULL) return WERR_INVALID_PARAM; /* A 'real' set function has preference */ if (key->context->ops->set_value == NULL) { - DEBUG(1, ("Backend '%s' doesn't support method set_value\n", + DEBUG(1, ("Backend '%s' doesn't support method set_value\n", key->context->ops->name)); return WERR_NOT_SUPPORTED; } @@ -234,15 +236,15 @@ _PUBLIC_ WERROR reg_val_set(struct registry_key *key, const char *value, /** * Get the security descriptor on a key. */ -_PUBLIC_ WERROR reg_get_sec_desc(TALLOC_CTX *ctx, - const struct registry_key *key, - struct security_descriptor **secdesc) +_PUBLIC_ WERROR reg_get_sec_desc(TALLOC_CTX *ctx, + const struct registry_key *key, + struct security_descriptor **secdesc) { if (key == NULL) return WERR_INVALID_PARAM; /* A 'real' set function has preference */ - if (key->context->ops->get_security == NULL) + if (key->context->ops->get_security == NULL) return WERR_NOT_SUPPORTED; return key->context->ops->get_security(ctx, key, secdesc); @@ -269,32 +271,32 @@ _PUBLIC_ WERROR reg_key_flush(struct registry_key *key) { if (key == NULL) return WERR_INVALID_PARAM; - + if (key->context->ops->flush_key == NULL) return WERR_NOT_SUPPORTED; return key->context->ops->flush_key(key); } -_PUBLIC_ WERROR reg_get_security(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - struct security_descriptor **security) +_PUBLIC_ WERROR reg_get_security(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + struct security_descriptor **security) { if (key == NULL) return WERR_INVALID_PARAM; - + if (key->context->ops->get_security == NULL) return WERR_NOT_SUPPORTED; return key->context->ops->get_security(mem_ctx, key, security); } -_PUBLIC_ WERROR reg_set_security(struct registry_key *key, - struct security_descriptor *security) +_PUBLIC_ WERROR reg_set_security(struct registry_key *key, + struct security_descriptor *security) { if (key == NULL) return WERR_INVALID_PARAM; - + if (key->context->ops->set_security == NULL) return WERR_NOT_SUPPORTED; diff --git a/source4/lib/registry/ldb.c b/source4/lib/registry/ldb.c index 8a34fa7a54..4a6ef65bc4 100644 --- a/source4/lib/registry/ldb.c +++ b/source4/lib/registry/ldb.c @@ -1,18 +1,18 @@ -/* +/* Unix SMB/CIFS implementation. Registry interface Copyright (C) Jelmer Vernooij 2004-2007. - + 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -23,10 +23,11 @@ #include "lib/ldb/include/ldb_errors.h" #include "db_wrap.h" #include "librpc/gen_ndr/winreg.h" +#include "param/param.h" static struct hive_operations reg_backend_ldb; -struct ldb_key_data +struct ldb_key_data { struct hive_key key; struct ldb_context *ldb; @@ -35,12 +36,15 @@ struct ldb_key_data int subkey_count, value_count; }; -static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char **name, - uint32_t *type, DATA_BLOB *data) +static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, + const char **name, uint32_t *type, + DATA_BLOB *data) { const struct ldb_val *val; if (name != NULL) - *name = talloc_strdup(mem_ctx, ldb_msg_find_attr_as_string(msg, "value", NULL)); + *name = talloc_strdup(mem_ctx, + ldb_msg_find_attr_as_string(msg, "value", + NULL)); if (type != NULL) *type = ldb_msg_find_attr_as_uint(msg, "type", 0); @@ -50,8 +54,9 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, c { case REG_SZ: case REG_EXPAND_SZ: - data->length = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, - val->data, val->length, (void **)&data->data); + data->length = convert_string_talloc(mem_ctx, CH_UTF8, CH_UTF16, + val->data, val->length, + (void **)&data->data); break; case REG_DWORD: { @@ -66,9 +71,10 @@ static void reg_ldb_unpack_value(TALLOC_CTX *mem_ctx, struct ldb_message *msg, c } } -static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, - TALLOC_CTX *mem_ctx, const char *name, - uint32_t type, DATA_BLOB data) +static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, + TALLOC_CTX *mem_ctx, + const char *name, + uint32_t type, DATA_BLOB data) { struct ldb_val val; struct ldb_message *msg = talloc_zero(mem_ctx, struct ldb_message); @@ -79,13 +85,17 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, switch (type) { case REG_SZ: case REG_EXPAND_SZ: - val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, - (void *)data.data, data.length, (void **)&val.data); + val.length = convert_string_talloc(mem_ctx, CH_UTF16, CH_UTF8, + (void *)data.data, + data.length, + (void **)&val.data); ldb_msg_add_value(msg, "data", &val, NULL); break; case REG_DWORD: - ldb_msg_add_string(msg, "data", talloc_asprintf(mem_ctx, "0x%x", IVAL(data.data, 0))); + ldb_msg_add_string(msg, "data", + talloc_asprintf(mem_ctx, "0x%x", + IVAL(data.data, 0))); break; default: ldb_msg_add_value(msg, "data", &data, NULL); @@ -93,7 +103,7 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, type_s = talloc_asprintf(mem_ctx, "%u", type); - ldb_msg_add_string(msg, "type", type_s); + ldb_msg_add_string(msg, "type", type_s); return msg; } @@ -102,20 +112,20 @@ static struct ldb_message *reg_ldb_pack_value(struct ldb_context *ctx, static int reg_close_ldb_key(struct ldb_key_data *key) { if (key->subkeys != NULL) { - talloc_free(key->subkeys); + talloc_free(key->subkeys); key->subkeys = NULL; } if (key->values != NULL) { - talloc_free(key->values); + talloc_free(key->values); key->values = NULL; } return 0; } -static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, - const struct hive_key *from, - const char *path, const char *add) +static struct ldb_dn *reg_path_to_ldb(TALLOC_CTX *mem_ctx, + const struct hive_key *from, + const char *path, const char *add) { TALLOC_CTX *local_ctx; struct ldb_dn *ret; @@ -172,7 +182,8 @@ static WERROR cache_subkeys(struct ldb_key_data *kd) ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(key=*)", NULL, &res); if (ret != LDB_SUCCESS) { - DEBUG(0, ("Error getting subkeys for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); + DEBUG(0, ("Error getting subkeys for '%s': %s\n", + ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); return WERR_FOOBAR; } @@ -189,10 +200,12 @@ static WERROR cache_values(struct ldb_key_data *kd) struct ldb_result *res; int ret; - ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, "(value=*)", NULL, &res); + ret = ldb_search(c, kd->dn, LDB_SCOPE_ONELEVEL, + "(value=*)", NULL, &res); if (ret != LDB_SUCCESS) { - DEBUG(0, ("Error getting values for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); + DEBUG(0, ("Error getting values for '%s': %s\n", + ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); return WERR_FOOBAR; } kd->value_count = res->count; @@ -202,11 +215,11 @@ static WERROR cache_values(struct ldb_key_data *kd) } -static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, - const struct hive_key *k, uint32_t idx, - const char **name, - const char **classname, - NTTIME *last_mod_time) +static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, + const struct hive_key *k, uint32_t idx, + const char **name, + const char **classname, + NTTIME *last_mod_time) { struct ldb_message_element *el; struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data); @@ -214,21 +227,21 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, /* Do a search if necessary */ if (kd->subkeys == NULL) { W_ERROR_NOT_OK_RETURN(cache_subkeys(kd)); - } + } - if (idx >= kd->subkey_count) + if (idx >= kd->subkey_count) return WERR_NO_MORE_ITEMS; el = ldb_msg_find_element(kd->subkeys[idx], "key"); SMB_ASSERT(el != NULL); SMB_ASSERT(el->num_values != 0); - + if (name != NULL) *name = talloc_strdup(mem_ctx, (char *)el->values[0].data); if (classname != NULL) *classname = NULL; /* TODO: Store properly */ - + if (last_mod_time != NULL) *last_mod_time = 0; /* TODO: we need to add this to the ldb backend properly */ @@ -236,8 +249,9 @@ static WERROR ldb_get_subkey_by_id(TALLOC_CTX *mem_ctx, return WERR_OK; } -static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct hive_key *k, int idx, - const char **name, uint32_t *data_type, DATA_BLOB *data) +static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct hive_key *k, + int idx, const char **name, + uint32_t *data_type, DATA_BLOB *data) { struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data); @@ -246,16 +260,18 @@ static WERROR ldb_get_value_by_id(TALLOC_CTX *mem_ctx, const struct hive_key *k, W_ERROR_NOT_OK_RETURN(cache_values(kd)); } - if(idx >= kd->value_count) return WERR_NO_MORE_ITEMS; + if (idx >= kd->value_count) + return WERR_NO_MORE_ITEMS; - reg_ldb_unpack_value(mem_ctx, kd->values[idx], - name, data_type, data); + reg_ldb_unpack_value(mem_ctx, kd->values[idx], + name, data_type, data); return WERR_OK; } -static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, - const char *name, uint32_t *data_type, DATA_BLOB *data) +static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, + const char *name, uint32_t *data_type, + DATA_BLOB *data) { struct ldb_key_data *kd = talloc_get_type(k, struct ldb_key_data); struct ldb_context *c = kd->ldb; @@ -268,7 +284,8 @@ static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, talloc_free(query); if (ret != LDB_SUCCESS) { - DEBUG(0, ("Error getting values for '%s': %s\n", ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); + DEBUG(0, ("Error getting values for '%s': %s\n", + ldb_dn_get_linearized(kd->dn), ldb_errstring(c))); return WERR_FOOBAR; } @@ -280,8 +297,8 @@ static WERROR ldb_get_value(TALLOC_CTX *mem_ctx, struct hive_key *k, return WERR_OK; } -static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, - const char *name, struct hive_key **key) +static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, + const char *name, struct hive_key **key) { struct ldb_result *res; struct ldb_dn *ldap_path; @@ -295,11 +312,12 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, ret = ldb_search(c, ldap_path, LDB_SCOPE_BASE, "(key=*)", NULL, &res); if (ret != LDB_SUCCESS) { - DEBUG(3, ("Error opening key '%s': %s\n", - ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); + DEBUG(3, ("Error opening key '%s': %s\n", + ldb_dn_get_linearized(ldap_path), ldb_errstring(c))); return WERR_FOOBAR; } else if (res->count == 0) { - DEBUG(3, ("Key '%s' not found\n", ldb_dn_get_linearized(ldap_path))); + DEBUG(3, ("Key '%s' not found\n", + ldb_dn_get_linearized(ldap_path))); talloc_free(res); return WERR_NOT_FOUND; } @@ -307,7 +325,7 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, newkd = talloc_zero(mem_ctx, struct ldb_key_data); newkd->key.ops = ®_backend_ldb; newkd->ldb = talloc_reference(newkd, kd->ldb); - newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn); + newkd->dn = ldb_dn_copy(mem_ctx, res->msgs[0]->dn); *key = (struct hive_key *)newkd; @@ -316,19 +334,19 @@ static WERROR ldb_open_key(TALLOC_CTX *mem_ctx, const struct hive_key *h, return WERR_OK; } -WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - struct hive_key **k) +WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + struct hive_key **k) { struct ldb_key_data *kd; struct ldb_context *wrap; - if (location == NULL) + if (location == NULL) return WERR_INVALID_PARAM; - wrap = ldb_wrap_connect(parent_ctx, location, session_info, - credentials, 0, NULL); + wrap = ldb_wrap_connect(parent_ctx, global_loadparm, + location, session_info, credentials, 0, NULL); if (wrap == NULL) { DEBUG(1, (__FILE__": unable to connect\n")); @@ -348,10 +366,10 @@ WERROR reg_open_ldb_file(TALLOC_CTX *parent_ctx, const char *location, return WERR_OK; } -static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, const struct hive_key *parent, - const char *name, const char *classname, - struct security_descriptor *sd, - struct hive_key **newkey) +static WERROR ldb_add_key(TALLOC_CTX *mem_ctx, const struct hive_key *parent, + const char *name, const char *classname, + struct security_descriptor *sd, + struct hive_key **newkey) { const struct ldb_key_data *parentkd = (const struct ldb_key_data *)parent; struct ldb_message *msg; @@ -364,13 +382,14 @@ static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, const struct hive_key *parent, ldb_msg_add_string(msg, "key", talloc_strdup(mem_ctx, name)); if (classname != NULL) - ldb_msg_add_string(msg, "classname", talloc_strdup(mem_ctx, classname)); + ldb_msg_add_string(msg, "classname", + talloc_strdup(mem_ctx, classname)); ret = ldb_add(parentkd->ldb, msg); if (ret < 0) { DEBUG(1, ("ldb_msg_add: %s\n", ldb_errstring(parentkd->ldb))); return WERR_FOOBAR; - } + } DEBUG(2, ("key added: %s\n", ldb_dn_get_linearized(msg->dn))); @@ -384,7 +403,7 @@ static WERROR ldb_add_key (TALLOC_CTX *mem_ctx, const struct hive_key *parent, return WERR_OK; } -static WERROR ldb_del_key (const struct hive_key *key, const char *child) +static WERROR ldb_del_key(const struct hive_key *key, const char *child) { int ret; struct ldb_key_data *parentkd = talloc_get_type(key, struct ldb_key_data); @@ -430,9 +449,9 @@ static WERROR ldb_del_value (struct hive_key *key, const char *child) return WERR_OK; } -static WERROR ldb_set_value(struct hive_key *parent, - const char *name, uint32_t type, - const DATA_BLOB data) +static WERROR ldb_set_value(struct hive_key *parent, + const char *name, uint32_t type, + const DATA_BLOB data) { struct ldb_message *msg; struct ldb_key_data *kd = talloc_get_type(parent, struct ldb_key_data); @@ -453,17 +472,17 @@ static WERROR ldb_set_value(struct hive_key *parent, return WERR_FOOBAR; } } - + talloc_free(mem_ctx); return WERR_OK; } -static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, - const struct hive_key *key, - const char **classname, - uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time) +static WERROR ldb_get_key_info(TALLOC_CTX *mem_ctx, + const struct hive_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time) { struct ldb_key_data *kd = talloc_get_type(key, struct ldb_key_data); diff --git a/source4/lib/registry/local.c b/source4/lib/registry/local.c index aefb11bde2..b54f0cf30a 100644 --- a/source4/lib/registry/local.c +++ b/source4/lib/registry/local.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. Transparent registry backend handling Copyright (C) Jelmer Vernooij 2003-2007. @@ -38,7 +38,7 @@ struct registry_local { struct mountpoint *prev, *next; } *mountpoints; - struct auth_session_info *session_info; + struct auth_session_info *session_info; struct cli_credentials *credentials; }; @@ -50,9 +50,9 @@ struct local_key { struct registry_key *reg_import_hive_key(struct registry_context *ctx, - struct hive_key *hive, - uint32_t predefined_key, - const char **elements) + struct hive_key *hive, + uint32_t predefined_key, + const char **elements) { struct local_key *local_key; struct reg_key_path parent_path; @@ -70,25 +70,26 @@ struct registry_key *reg_import_hive_key(struct registry_context *ctx, static WERROR local_open_key(TALLOC_CTX *mem_ctx, - struct registry_key *parent, - const char *path, - struct registry_key **result) + struct registry_key *parent, + const char *path, + struct registry_key **result) { char *orig = talloc_strdup(mem_ctx, path), - *curbegin = orig, + *curbegin = orig, *curend = strchr(orig, '\\'); - struct local_key *local_parent = talloc_get_type(parent, struct local_key); + struct local_key *local_parent = talloc_get_type(parent, + struct local_key); struct hive_key *curkey = local_parent->hive_key; WERROR error; const char **elements = NULL; int el; if (local_parent->path.elements != NULL) { - elements = talloc_array(mem_ctx, const char *, - str_list_length(local_parent->path.elements) + 1); + elements = talloc_array(mem_ctx, const char *, + str_list_length(local_parent->path.elements) + 1); for (el = 0; local_parent->path.elements[el] != NULL; el++) { - elements[el] = talloc_reference(elements, - local_parent->path.elements[el]); + elements[el] = talloc_reference(elements, + local_parent->path.elements[el]); } elements[el] = NULL; } else { @@ -103,94 +104,97 @@ static WERROR local_open_key(TALLOC_CTX *mem_ctx, elements[el] = talloc_strdup(elements, curbegin); el++; elements[el] = NULL; - error = hive_get_key_by_name(mem_ctx, curkey, curbegin, &curkey); + error = hive_get_key_by_name(mem_ctx, curkey, + curbegin, &curkey); if (!W_ERROR_IS_OK(error)) { - DEBUG(2, ("Opening key %s failed: %s\n", curbegin, win_errstr(error))); + DEBUG(2, ("Opening key %s failed: %s\n", curbegin, + win_errstr(error))); talloc_free(orig); return error; } - if (curend == NULL) + if (curend == NULL) break; curbegin = curend + 1; curend = strchr(curbegin, '\\'); } talloc_free(orig); - *result = reg_import_hive_key(local_parent->global.context, curkey, - local_parent->path.predefined_key, - talloc_steal(curkey, elements)); - + *result = reg_import_hive_key(local_parent->global.context, curkey, + local_parent->path.predefined_key, + talloc_steal(curkey, elements)); + return WERR_OK; } -WERROR local_get_predefined_key (const struct registry_context *ctx, - uint32_t key_id, struct registry_key **key) -{ - struct registry_local *rctx = talloc_get_type(ctx, struct registry_local); +WERROR local_get_predefined_key(const struct registry_context *ctx, + uint32_t key_id, struct registry_key **key) +{ + struct registry_local *rctx = talloc_get_type(ctx, + struct registry_local); struct mountpoint *mp; for (mp = rctx->mountpoints; mp != NULL; mp = mp->next) { - if (mp->path.predefined_key == key_id && + if (mp->path.predefined_key == key_id && mp->path.elements == NULL) break; } if (mp == NULL) return WERR_NOT_FOUND; - - *key = reg_import_hive_key(ctx, mp->key, - mp->path.predefined_key, - mp->path.elements - ); + + *key = reg_import_hive_key(ctx, mp->key, + mp->path.predefined_key, + mp->path.elements); return WERR_OK; } -WERROR local_enum_key(TALLOC_CTX *mem_ctx, - const struct registry_key *key, uint32_t idx, - const char **name, - const char **keyclass, - NTTIME *last_changed_time) +static WERROR local_enum_key(TALLOC_CTX *mem_ctx, + const struct registry_key *key, uint32_t idx, + const char **name, + const char **keyclass, + NTTIME *last_changed_time) { const struct local_key *local = (const struct local_key *)key; - return hive_enum_key(mem_ctx, local->hive_key, idx, name, keyclass, - last_changed_time); + return hive_enum_key(mem_ctx, local->hive_key, idx, name, keyclass, + last_changed_time); } -static WERROR local_create_key (TALLOC_CTX *mem_ctx, - struct registry_key *parent_key, - const char *name, - const char *key_class, - struct security_descriptor *security, - struct registry_key **key) +static WERROR local_create_key(TALLOC_CTX *mem_ctx, + struct registry_key *parent_key, + const char *name, + const char *key_class, + struct security_descriptor *security, + struct registry_key **key) { const struct local_key *local_parent; struct hive_key *hivekey; const char **elements; int i; - char *last_part; + const char *last_part; last_part = strrchr(name, '\\'); if (last_part == NULL) { last_part = name; local_parent = (const struct local_key *)parent_key; } else { - W_ERROR_NOT_OK_RETURN(reg_open_key(mem_ctx, parent_key, - talloc_strndup(mem_ctx, name, last_part-name), - &local_parent)); + W_ERROR_NOT_OK_RETURN(reg_open_key(mem_ctx, parent_key, + talloc_strndup(mem_ctx, name, last_part-name), + &local_parent)); last_part++; } - W_ERROR_NOT_OK_RETURN(hive_key_add_name(mem_ctx, local_parent->hive_key, - last_part, key_class, security, &hivekey)); + W_ERROR_NOT_OK_RETURN(hive_key_add_name(mem_ctx, local_parent->hive_key, + last_part, key_class, security, + &hivekey)); if (local_parent->path.elements != NULL) { - elements = talloc_array(hivekey, const char *, - str_list_length(local_parent->path.elements)+2); + elements = talloc_array(hivekey, const char *, + str_list_length(local_parent->path.elements)+2); for (i = 0; local_parent->path.elements[i] != NULL; i++) { - elements[i] = talloc_reference(elements, - local_parent->path.elements[i]); + elements[i] = talloc_reference(elements, + local_parent->path.elements[i]); } } else { elements = talloc_array(hivekey, const char *, 2); @@ -200,75 +204,75 @@ static WERROR local_create_key (TALLOC_CTX *mem_ctx, elements[i] = talloc_strdup(elements, name); elements[i+1] = NULL; - *key = reg_import_hive_key(local_parent->global.context, hivekey, - local_parent->path.predefined_key, - elements); + *key = reg_import_hive_key(local_parent->global.context, hivekey, + local_parent->path.predefined_key, + elements); return WERR_OK; } -static WERROR local_set_value (struct registry_key *key, const char *name, - uint32_t type, const DATA_BLOB data) +static WERROR local_set_value(struct registry_key *key, const char *name, + uint32_t type, const DATA_BLOB data) { struct local_key *local = (struct local_key *)key; return hive_set_value(local->hive_key, name, type, data); } -static WERROR local_get_value (TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char *name, uint32_t *type, DATA_BLOB *data) +static WERROR local_get_value(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char *name, uint32_t *type, DATA_BLOB *data) { const struct local_key *local = (const struct local_key *)key; return hive_get_value(mem_ctx, local->hive_key, name, type, data); } -static WERROR local_enum_value (TALLOC_CTX *mem_ctx, - const struct registry_key *key, uint32_t idx, - const char **name, - uint32_t *type, - DATA_BLOB *data) +static WERROR local_enum_value(TALLOC_CTX *mem_ctx, + const struct registry_key *key, uint32_t idx, + const char **name, + uint32_t *type, + DATA_BLOB *data) { const struct local_key *local = (const struct local_key *)key; - return hive_get_value_by_index(mem_ctx, local->hive_key, idx, - name, type, data); + return hive_get_value_by_index(mem_ctx, local->hive_key, idx, + name, type, data); } -static WERROR local_delete_key (struct registry_key *key, const char *name) +static WERROR local_delete_key(struct registry_key *key, const char *name) { const struct local_key *local = (const struct local_key *)key; return hive_key_del(local->hive_key, name); } -static WERROR local_delete_value (struct registry_key *key, const char *name) +static WERROR local_delete_value(struct registry_key *key, const char *name) { const struct local_key *local = (const struct local_key *)key; return hive_del_value(local->hive_key, name); } -static WERROR local_flush_key (struct registry_key *key) +static WERROR local_flush_key(struct registry_key *key) { const struct local_key *local = (const struct local_key *)key; return hive_key_flush(local->hive_key); } -static WERROR local_get_key_info (TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char **classname, - uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time) +static WERROR local_get_key_info(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time) { const struct local_key *local = (const struct local_key *)key; - return hive_key_get_info(mem_ctx, local->hive_key, - classname, num_subkeys, num_values, - last_change_time); + return hive_key_get_info(mem_ctx, local->hive_key, + classname, num_subkeys, num_values, + last_change_time); } const static struct registry_operations local_ops = { @@ -286,11 +290,12 @@ const static struct registry_operations local_ops = { .get_key_info = local_get_key_info, }; -WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials) +WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials) { - struct registry_local *ret = talloc_zero(mem_ctx, struct registry_local); + struct registry_local *ret = talloc_zero(mem_ctx, + struct registry_local); W_ERROR_HAVE_NO_MEMORY(ret); @@ -299,16 +304,17 @@ WERROR reg_open_local(TALLOC_CTX *mem_ctx, struct registry_context **ctx, ret->credentials = credentials; *ctx = (struct registry_context *)ret; - + return WERR_OK; } -WERROR reg_mount_hive(struct registry_context *rctx, - struct hive_key *hive_key, - uint32_t key_id, - const char **elements) +WERROR reg_mount_hive(struct registry_context *rctx, + struct hive_key *hive_key, + uint32_t key_id, + const char **elements) { - struct registry_local *reg_local = talloc_get_type(rctx, struct registry_local); + struct registry_local *reg_local = talloc_get_type(rctx, + struct registry_local); struct mountpoint *mp = talloc(rctx, struct mountpoint); int i = 0; @@ -316,11 +322,11 @@ WERROR reg_mount_hive(struct registry_context *rctx, mp->prev = mp->next = NULL; mp->key = hive_key; if (elements != NULL) { - mp->path.elements = talloc_array(mp, const char *, - str_list_length(elements)); + mp->path.elements = talloc_array(mp, const char *, + str_list_length(elements)); for (i = 0; elements[i] != NULL; i++) { - mp->path.elements[i] = talloc_reference(mp->path.elements, - elements[i]); + mp->path.elements[i] = talloc_reference(mp->path.elements, + elements[i]); } mp->path.elements[i] = NULL; } else { diff --git a/source4/lib/registry/patchfile.c b/source4/lib/registry/patchfile.c index 8df873d56b..e5d9a26618 100644 --- a/source4/lib/registry/patchfile.c +++ b/source4/lib/registry/patchfile.c @@ -1,7 +1,7 @@ -/* +/* Unix SMB/CIFS implementation. Reading registry patch files - + Copyright (C) Jelmer Vernooij 2004-2007 Copyright (C) Wilco Baan Hofman 2006 @@ -9,12 +9,12 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>. */ @@ -25,18 +25,22 @@ #include "system/filesys.h" -_PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *callbacks, void *callback_data); +_PUBLIC_ WERROR reg_preg_diff_load(int fd, + const struct reg_diff_callbacks *callbacks, + void *callback_data); -_PUBLIC_ WERROR reg_dotreg_diff_load(int fd, const struct reg_diff_callbacks *callbacks, void *callback_data); +_PUBLIC_ WERROR reg_dotreg_diff_load(int fd, + const struct reg_diff_callbacks *callbacks, + void *callback_data); /* * Generate difference between two keys */ -WERROR reg_generate_diff_key(struct registry_key *oldkey, - struct registry_key *newkey, - const char *path, - const struct reg_diff_callbacks *callbacks, - void *callback_data) +WERROR reg_generate_diff_key(struct registry_key *oldkey, + struct registry_key *newkey, + const char *path, + const struct reg_diff_callbacks *callbacks, + void *callback_data) { int i; struct registry_key *t1, *t2; @@ -48,11 +52,12 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, new_num_subkeys, new_num_values; if (oldkey != NULL) { - error = reg_key_get_info(mem_ctx, oldkey, NULL, &old_num_subkeys, &old_num_values, - NULL); + error = reg_key_get_info(mem_ctx, oldkey, NULL, + &old_num_subkeys, &old_num_values, + NULL); if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error occured while getting key info: %s\n", - win_errstr(error))); + DEBUG(0, ("Error occured while getting key info: %s\n", + win_errstr(error))); return error; } } else { @@ -62,11 +67,12 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, /* Subkeys that were deleted */ for (i = 0; i < old_num_subkeys; i++) { - error1 = reg_key_get_subkey_by_index(mem_ctx, oldkey, i, &keyname1, - NULL, NULL); + error1 = reg_key_get_subkey_by_index(mem_ctx, oldkey, i, + &keyname1, + NULL, NULL); if (!W_ERROR_IS_OK(error1)) { - DEBUG(0, ("Error occured while getting subkey by index: %s\n", - win_errstr(error2))); + DEBUG(0, ("Error occured while getting subkey by index: %s\n", + win_errstr(error2))); continue; } @@ -81,8 +87,8 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, } if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - DEBUG(0, ("Error occured while getting subkey by name: %s\n", - win_errstr(error2))); + DEBUG(0, ("Error occured while getting subkey by name: %s\n", + win_errstr(error2))); talloc_free(mem_ctx); return error2; } @@ -90,15 +96,16 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, /* newkey didn't have such a subkey, add del diff */ tmppath = talloc_asprintf(mem_ctx, "%s\\%s", path, keyname1); callbacks->del_key(callback_data, tmppath); - talloc_free(tmppath); + talloc_free(tmppath); } if (newkey != NULL) { - error = reg_key_get_info(mem_ctx, newkey, NULL, &new_num_subkeys, &new_num_values, - NULL); + error = reg_key_get_info(mem_ctx, newkey, NULL, + &new_num_subkeys, &new_num_values, + NULL); if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error occured while getting key info: %s\n", - win_errstr(error))); + DEBUG(0, ("Error occured while getting key info: %s\n", + win_errstr(error))); return error; } } else { @@ -108,28 +115,29 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, /* Subkeys that were added */ for(i = 0; i < new_num_subkeys; i++) { - error1 = reg_key_get_subkey_by_index(mem_ctx, newkey, i, &keyname1, - NULL, NULL); + error1 = reg_key_get_subkey_by_index(mem_ctx, newkey, + i, &keyname1, + NULL, NULL); if (!W_ERROR_IS_OK(error1)) { - DEBUG(0, ("Error occured while getting subkey by index: %s\n", - win_errstr(error1))); + DEBUG(0, ("Error occured while getting subkey by index: %s\n", + win_errstr(error1))); talloc_free(mem_ctx); return error1; } if (oldkey != NULL) { error2 = reg_open_key(mem_ctx, oldkey, keyname1, &t1); - + if (W_ERROR_IS_OK(error2)) continue; } else { t1 = NULL; error2 = WERR_DEST_NOT_FOUND; } - + if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - DEBUG(0, ("Error occured while getting subkey by name: %s\n", - win_errstr(error2))); + DEBUG(0, ("Error occured while getting subkey by name: %s\n", + win_errstr(error2))); talloc_free(mem_ctx); return error2; } @@ -141,7 +149,8 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, W_ERROR_NOT_OK_RETURN( reg_open_key(mem_ctx, newkey, keyname1, &t2)); - reg_generate_diff_key(t1, t2, tmppath, callbacks, callback_data); + reg_generate_diff_key(t1, t2, tmppath, + callbacks, callback_data); talloc_free(tmppath); } @@ -151,56 +160,59 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, uint32_t type1, type2; DATA_BLOB contents1, contents2; - error1 = reg_key_get_value_by_index(mem_ctx, newkey, i, - &name, &type1, &contents1); + error1 = reg_key_get_value_by_index(mem_ctx, newkey, i, + &name, &type1, &contents1); if (!W_ERROR_IS_OK(error1)) { - DEBUG(0, ("Unable to get key by index: %s\n", - win_errstr(error1))); + DEBUG(0, ("Unable to get key by index: %s\n", + win_errstr(error1))); talloc_free(mem_ctx); return error1; } if (oldkey != NULL) { - error2 = reg_key_get_value_by_name(mem_ctx, oldkey, name, - &type2, &contents2); - } else + error2 = reg_key_get_value_by_name(mem_ctx, oldkey, + name, &type2, + &contents2); + } else error2 = WERR_DEST_NOT_FOUND; - - if(!W_ERROR_IS_OK(error2) && + + if(!W_ERROR_IS_OK(error2) && !W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - DEBUG(0, ("Error occured while getting value by name: %s\n", - win_errstr(error2))); + DEBUG(0, ("Error occured while getting value by name: %s\n", + win_errstr(error2))); talloc_free(mem_ctx); return error2; } - if (W_ERROR_IS_OK(error2) && data_blob_cmp(&contents1, &contents2) == 0) + if (W_ERROR_IS_OK(error2) && + data_blob_cmp(&contents1, &contents2) == 0) continue; - callbacks->set_value(callback_data, path, name, type1, contents1); + callbacks->set_value(callback_data, path, name, + type1, contents1); } /* Values that were deleted */ for (i = 0; i < old_num_values; i++) { const char *name; - error1 = reg_key_get_value_by_index(mem_ctx, oldkey, i, &name, - NULL, NULL); + error1 = reg_key_get_value_by_index(mem_ctx, oldkey, i, &name, + NULL, NULL); if (!W_ERROR_IS_OK(error1)) { - DEBUG(0, ("Error ocurred getting value by index: %s\n", - win_errstr(error1))); + DEBUG(0, ("Error ocurred getting value by index: %s\n", + win_errstr(error1))); talloc_free(mem_ctx); return error1; } - error2 = reg_key_get_value_by_name(mem_ctx, newkey, name, NULL, - NULL); + error2 = reg_key_get_value_by_name(mem_ctx, newkey, name, NULL, + NULL); if (W_ERROR_IS_OK(error2)) continue; if (!W_ERROR_EQUAL(error2, WERR_DEST_NOT_FOUND)) { - DEBUG(0, ("Error occured while getting value by name: %s\n", - win_errstr(error2))); + DEBUG(0, ("Error occured while getting value by name: %s\n", + win_errstr(error2))); return error2; } @@ -212,10 +224,10 @@ WERROR reg_generate_diff_key(struct registry_key *oldkey, } /** - * Generate diff between two registry contexts + * Generate diff between two registry contexts */ -_PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, - struct registry_context *ctx2, +_PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, + struct registry_context *ctx2, const struct reg_diff_callbacks *callbacks, void *callback_data) { @@ -225,21 +237,27 @@ _PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, for(i = HKEY_FIRST; i <= HKEY_LAST; i++) { struct registry_key *r1 = NULL, *r2 = NULL; error = reg_get_predefined_key(ctx1, i, &r1); - if (!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NOT_FOUND)) { - DEBUG(0, ("Unable to open hive %s for backend 1\n", reg_get_predef_name(i))); + if (!W_ERROR_IS_OK(error) && + !W_ERROR_EQUAL(error, WERR_NOT_FOUND)) { + DEBUG(0, ("Unable to open hive %s for backend 1\n", + reg_get_predef_name(i))); } - + error = reg_get_predefined_key(ctx2, i, &r2); - if (!W_ERROR_IS_OK(error) && !W_ERROR_EQUAL(error, WERR_NOT_FOUND)) { - DEBUG(0, ("Unable to open hive %s for backend 2\n", reg_get_predef_name(i))); + if (!W_ERROR_IS_OK(error) && + !W_ERROR_EQUAL(error, WERR_NOT_FOUND)) { + DEBUG(0, ("Unable to open hive %s for backend 2\n", + reg_get_predef_name(i))); } if (r1 == NULL && r2 == NULL) continue; - error = reg_generate_diff_key(r1, r2, reg_get_predef_name(i), callbacks, callback_data); + error = reg_generate_diff_key(r1, r2, reg_get_predef_name(i), + callbacks, callback_data); if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Unable to determine diff: %s\n", win_errstr(error))); + DEBUG(0, ("Unable to determine diff: %s\n", + win_errstr(error))); return error; } } @@ -252,21 +270,23 @@ _PUBLIC_ WERROR reg_generate_diff(struct registry_context *ctx1, /** * Load diff file */ -_PUBLIC_ WERROR reg_diff_load(const char *filename, - const struct reg_diff_callbacks *callbacks, - void *callback_data) +_PUBLIC_ WERROR reg_diff_load(const char *filename, + const struct reg_diff_callbacks *callbacks, + void *callback_data) { int fd; char hdr[4]; - + fd = open(filename, O_RDONLY, 0); if (fd == -1) { - DEBUG(0, ("Error opening registry patch file `%s'\n", filename)); + DEBUG(0, ("Error opening registry patch file `%s'\n", + filename)); return WERR_GENERAL_FAILURE; } if (read(fd, &hdr, 4) != 4) { - DEBUG(0, ("Error reading registry patch file `%s'\n", filename)); + DEBUG(0, ("Error reading registry patch file `%s'\n", + filename)); return WERR_GENERAL_FAILURE; } @@ -279,8 +299,8 @@ _PUBLIC_ WERROR reg_diff_load(const char *filename, } else if (strncmp(hdr, "regf", 4) == 0) { /* Must be a REGF NTConfig.pol file */ return reg_regf_diff_load(diff, fd); - } else -#endif + } else +#endif if (strncmp(hdr, "PReg", 4) == 0) { /* Must be a GPO Registry.pol file */ return reg_preg_diff_load(fd, callbacks, callback_data); @@ -293,24 +313,26 @@ _PUBLIC_ WERROR reg_diff_load(const char *filename, /** * The reg_diff_apply functions */ -static WERROR reg_diff_apply_add_key(void *_ctx, const char *key_name) +static WERROR reg_diff_apply_add_key(void *_ctx, const char *key_name) { - struct registry_context *ctx = _ctx; + struct registry_context *ctx = (struct registry_context *)_ctx; struct registry_key *tmp; WERROR error; error = reg_key_add_abs(ctx, ctx, key_name, 0, NULL, &tmp); - if (!W_ERROR_EQUAL(error, WERR_ALREADY_EXISTS) && !W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error adding new key '%s': %s\n", key_name, win_errstr(error))); + if (!W_ERROR_EQUAL(error, WERR_ALREADY_EXISTS) && + !W_ERROR_IS_OK(error)) { + DEBUG(0, ("Error adding new key '%s': %s\n", + key_name, win_errstr(error))); return error; } return WERR_OK; } -static WERROR reg_diff_apply_del_key(void *_ctx, const char *key_name) +static WERROR reg_diff_apply_del_key(void *_ctx, const char *key_name) { - struct registry_context *ctx = _ctx; + struct registry_context *ctx = (struct registry_context *)_ctx; WERROR error; error = reg_key_del_abs(ctx, key_name); @@ -319,16 +341,18 @@ static WERROR reg_diff_apply_del_key(void *_ctx, const char *key_name) DEBUG(0, ("Unable to delete key '%s'\n", key_name)); return error; } - + return WERR_OK; } -static WERROR reg_diff_apply_set_value(void *_ctx, const char *path, const char *value_name, uint32_t value_type, DATA_BLOB value) +static WERROR reg_diff_apply_set_value(void *_ctx, const char *path, + const char *value_name, + uint32_t value_type, DATA_BLOB value) { - struct registry_context *ctx = _ctx; + struct registry_context *ctx = (struct registry_context *)_ctx; struct registry_key *tmp; WERROR error; - + /* Open key */ error = reg_open_key_abs(ctx, ctx, path, &tmp); @@ -338,22 +362,23 @@ static WERROR reg_diff_apply_set_value(void *_ctx, const char *path, const char } /* Set value */ - error = reg_val_set(tmp, value_name, + error = reg_val_set(tmp, value_name, value_type, value); if (!W_ERROR_IS_OK(error)) { DEBUG(0, ("Error setting value '%s'\n", value_name)); return error; - } - + } + return WERR_OK; } -static WERROR reg_diff_apply_del_value (void *_ctx, const char *key_name, const char *value_name) +static WERROR reg_diff_apply_del_value(void *_ctx, const char *key_name, + const char *value_name) { - struct registry_context *ctx = _ctx; + struct registry_context *ctx = (struct registry_context *)_ctx; struct registry_key *tmp; WERROR error; - + /* Open key */ error = reg_open_key_abs(ctx, ctx, key_name, &tmp); @@ -367,14 +392,14 @@ static WERROR reg_diff_apply_del_value (void *_ctx, const char *key_name, const DEBUG(0, ("Error deleting value '%s'\n", value_name)); return error; } - + return WERR_OK; } static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name) { - struct registry_context *ctx = _ctx; + struct registry_context *ctx = (struct registry_context *)_ctx; struct registry_key *key; WERROR error; int i; @@ -387,26 +412,28 @@ static WERROR reg_diff_apply_del_all_values(void *_ctx, const char *key_name) return error; } - W_ERROR_NOT_OK_RETURN(reg_key_get_info(ctx, key, - NULL, - NULL, - &num_values, - NULL)); + W_ERROR_NOT_OK_RETURN(reg_key_get_info(ctx, key, + NULL, + NULL, + &num_values, + NULL)); for (i = 0; i < num_values; i++) { const char *name; - W_ERROR_NOT_OK_RETURN(reg_key_get_value_by_index(ctx, key, i, &name, - NULL, NULL)); + W_ERROR_NOT_OK_RETURN(reg_key_get_value_by_index(ctx, key, i, + &name, + NULL, NULL)); W_ERROR_NOT_OK_RETURN(reg_del_value(key, name)); } return WERR_OK; } -/** - * Apply diff to a registry context +/** + * Apply diff to a registry context */ -_PUBLIC_ WERROR reg_diff_apply (const char *filename, struct registry_context *ctx) +_PUBLIC_ WERROR reg_diff_apply(const char *filename, + struct registry_context *ctx) { struct reg_diff_callbacks callbacks; diff --git a/source4/lib/registry/patchfile.h b/source4/lib/registry/patchfile.h index 1c0b195a8c..4c0599b2f3 100644 --- a/source4/lib/registry/patchfile.h +++ b/source4/lib/registry/patchfile.h @@ -1,52 +1,55 @@ -/* +/* Unix SMB/CIFS implementation. Patchfile interface Copyright (C) Jelmer Vernooij 2006 Copyright (C) Wilco Baan Hofman 2006 - + 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. */ #ifndef _PATCHFILE_H -#define _PATCHFILE_H +#define _PATCHFILE_H #include "lib/registry/registry.h" struct reg_diff_callbacks { WERROR (*add_key) (void *callback_data, const char *key_name); - WERROR (*set_value) (void *callback_data, const char *key_name, - const char *value_name, uint32_t value_type, DATA_BLOB value); - WERROR (*del_value) (void *callback_data, const char *key_name, const char *value_name); + WERROR (*set_value) (void *callback_data, const char *key_name, + const char *value_name, uint32_t value_type, + DATA_BLOB value); + WERROR (*del_value) (void *callback_data, const char *key_name, + const char *value_name); WERROR (*del_key) (void *callback_data, const char *key_name); WERROR (*del_all_values) (void *callback_data, const char *key_name); WERROR (*done) (void *callback_data); }; -WERROR reg_diff_apply (const char *filename, - struct registry_context *ctx); - -WERROR reg_generate_diff(struct registry_context *ctx1, - struct registry_context *ctx2, - const struct reg_diff_callbacks *callbacks, - void *callback_data); -WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, - struct reg_diff_callbacks **callbacks, void **callback_data); -WERROR reg_generate_diff_key(struct registry_key *oldkey, - struct registry_key *newkey, - const char *path, - const struct reg_diff_callbacks *callbacks, - void *callback_data); +WERROR reg_diff_apply (const char *filename, + struct registry_context *ctx); + +WERROR reg_generate_diff(struct registry_context *ctx1, + struct registry_context *ctx2, + const struct reg_diff_callbacks *callbacks, + void *callback_data); +WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, + struct reg_diff_callbacks **callbacks, + void **callback_data); +WERROR reg_generate_diff_key(struct registry_key *oldkey, + struct registry_key *newkey, + const char *path, + const struct reg_diff_callbacks *callbacks, + void *callback_data); #endif /* _PATCHFILE_H */ diff --git a/source4/lib/registry/patchfile_dotreg.c b/source4/lib/registry/patchfile_dotreg.c index 1b4bffe819..ebcafc92af 100644 --- a/source4/lib/registry/patchfile_dotreg.c +++ b/source4/lib/registry/patchfile_dotreg.c @@ -1,7 +1,7 @@ -/* +/* Unix SMB/CIFS implementation. Reading .REG files - + Copyright (C) Jelmer Vernooij 2004-2007 Copyright (C) Wilco Baan Hofman 2006 @@ -9,12 +9,12 @@ 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. @@ -40,37 +40,39 @@ struct dotreg_data { static WERROR reg_dotreg_diff_add_key(void *_data, const char *key_name) { - struct dotreg_data *data = _data; + struct dotreg_data *data = (struct dotreg_data *)_data; fdprintf(data->fd, "\n[%s]\n", key_name); - + return WERR_OK; } static WERROR reg_dotreg_diff_del_key(void *_data, const char *key_name) { - struct dotreg_data *data = _data; + struct dotreg_data *data = (struct dotreg_data *)_data; fdprintf(data->fd, "\n[-%s]\n", key_name); - + return WERR_OK; } -static WERROR reg_dotreg_diff_set_value(void *_data, const char *path, - const char *value_name, uint32_t value_type, DATA_BLOB value) +static WERROR reg_dotreg_diff_set_value(void *_data, const char *path, + const char *value_name, + uint32_t value_type, DATA_BLOB value) { - struct dotreg_data *data = _data; + struct dotreg_data *data = (struct dotreg_data *)_data; fdprintf(data->fd, "\"%s\"=%s:%s\n", - value_name, str_regtype(value_type), + value_name, str_regtype(value_type), reg_val_data_string(NULL, value_type, value)); - + return WERR_OK; } -static WERROR reg_dotreg_diff_del_value(void *_data, const char *path, const char *value_name) +static WERROR reg_dotreg_diff_del_value(void *_data, const char *path, + const char *value_name) { - struct dotreg_data *data = _data; + struct dotreg_data *data = (struct dotreg_data *)_data; fdprintf(data->fd, "\"%s\"=-\n", value_name); @@ -79,7 +81,7 @@ static WERROR reg_dotreg_diff_del_value(void *_data, const char *path, const cha static WERROR reg_dotreg_diff_done(void *_data) { - struct dotreg_data *data = _data; + struct dotreg_data *data = (struct dotreg_data *)_data; close(data->fd); talloc_free(data); @@ -87,7 +89,8 @@ static WERROR reg_dotreg_diff_done(void *_data) return WERR_OK; } -static WERROR reg_dotreg_diff_del_all_values (void *callback_data, const char *key_name) +static WERROR reg_dotreg_diff_del_all_values(void *callback_data, + const char *key_name) { return WERR_NOT_SUPPORTED; } @@ -95,8 +98,9 @@ static WERROR reg_dotreg_diff_del_all_values (void *callback_data, const char *k /** * Save registry diff */ -_PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, - struct reg_diff_callbacks **callbacks, void **callback_data) +_PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, + struct reg_diff_callbacks **callbacks, + void **callback_data) { struct dotreg_data *data; @@ -125,12 +129,14 @@ _PUBLIC_ WERROR reg_dotreg_diff_save(TALLOC_CTX *ctx, const char *filename, (*callbacks)->done = reg_dotreg_diff_done; return WERR_OK; -} +} /** * Load diff file */ -_PUBLIC_ WERROR reg_dotreg_diff_load(int fd, const struct reg_diff_callbacks *callbacks, void *callback_data) +_PUBLIC_ WERROR reg_dotreg_diff_load(int fd, + const struct reg_diff_callbacks *callbacks, + void *callback_data) { char *line, *p, *q; char *curkey = NULL; @@ -151,8 +157,8 @@ _PUBLIC_ WERROR reg_dotreg_diff_load(int fd, const struct reg_diff_callbacks *ca /* Ignore comments and empty lines */ if (strlen(line) == 0 || line[0] == ';') { talloc_free(line); - - if (curkey) { + + if (curkey) { talloc_free(curkey); } curkey = NULL; @@ -170,9 +176,11 @@ _PUBLIC_ WERROR reg_dotreg_diff_load(int fd, const struct reg_diff_callbacks *ca if (line[1] == '-') { curkey = talloc_strndup(line, line+2, strlen(line)-3); - error = callbacks->del_key(callback_data, curkey); + error = callbacks->del_key(callback_data, + curkey); if (!W_ERROR_IS_OK(error)) { - DEBUG(0,("Error deleting key %s\n", curkey)); + DEBUG(0,("Error deleting key %s\n", + curkey)); talloc_free(mem_ctx); return error; } @@ -212,9 +220,11 @@ _PUBLIC_ WERROR reg_dotreg_diff_load(int fd, const struct reg_diff_callbacks *ca /* Delete value */ if (strcmp(p, "-") == 0) { - error = callbacks->del_value(callback_data, curkey, line); + error = callbacks->del_value(callback_data, + curkey, line); if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error deleting value %s in key %s\n", line, curkey)); + DEBUG(0, ("Error deleting value %s in key %s\n", + line, curkey)); talloc_free(mem_ctx); return error; } @@ -222,18 +232,21 @@ _PUBLIC_ WERROR reg_dotreg_diff_load(int fd, const struct reg_diff_callbacks *ca talloc_free(line); continue; } - + q = strchr_m(p, ':'); if (q) { - *q = '\0'; + *q = '\0'; q++; } - reg_string_to_val(line, q?p:"REG_SZ", q?q:p, &value_type, &value); - - error = callbacks->set_value(callback_data, curkey, line, value_type, value); + reg_string_to_val(line, q?p:"REG_SZ", q?q:p, + &value_type, &value); + + error = callbacks->set_value(callback_data, curkey, line, + value_type, value); if (!W_ERROR_IS_OK(error)) { - DEBUG(0, ("Error setting value for %s in %s\n", line, curkey)); + DEBUG(0, ("Error setting value for %s in %s\n", + line, curkey)); talloc_free(mem_ctx); return error; } diff --git a/source4/lib/registry/patchfile_preg.c b/source4/lib/registry/patchfile_preg.c index 1c8d76538a..90a4f2529a 100644 --- a/source4/lib/registry/patchfile_preg.c +++ b/source4/lib/registry/patchfile_preg.c @@ -1,19 +1,19 @@ -/* +/* Unix SMB/CIFS implementation. Reading Registry.pol PReg registry files - + Copyright (C) Wilco Baan Hofman 2006 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. @@ -21,6 +21,7 @@ #include "includes.h" #include "lib/registry/registry.h" +#include "lib/registry/patchfile.h" #include "system/filesys.h" #include "pstring.h" @@ -42,37 +43,40 @@ static WERROR preg_read_utf16(int fd, char *c) /* FIXME These functions need to be implemented */ static WERROR reg_preg_diff_add_key(void *_data, const char *key_name) { - struct preg_data *data = _data; + struct preg_data *data = (struct preg_data *)_data; return WERR_OK; } static WERROR reg_preg_diff_del_key(void *_data, const char *key_name) { - struct preg_data *data = _data; + struct preg_data *data = (struct preg_data *)_data; return WERR_OK; } -static WERROR reg_preg_diff_set_value(void *_data, const char *key_name, const char *value_name, uint32_t value_type, DATA_BLOB value_data) +static WERROR reg_preg_diff_set_value(void *_data, const char *key_name, + const char *value_name, + uint32_t value_type, DATA_BLOB value_data) { - struct preg_data *data = _data; + struct preg_data *data = (struct preg_data *)_data; return WERR_OK; } -static WERROR reg_preg_diff_del_value(void *_data, const char *key_name, const char *value_name) +static WERROR reg_preg_diff_del_value(void *_data, const char *key_name, + const char *value_name) { - struct preg_data *data = _data; + struct preg_data *data = (struct preg_data *)_data; return WERR_OK; } static WERROR reg_preg_diff_del_all_values(void *_data, const char *key_name) { - struct preg_data *data = _data; + struct preg_data *data = (struct preg_data *)_data; return WERR_OK; } static WERROR reg_preg_diff_done(void *_data) { - struct preg_data *data = _data; + struct preg_data *data = (struct preg_data *)_data; close(data->fd); talloc_free(data); @@ -82,14 +86,16 @@ static WERROR reg_preg_diff_done(void *_data) /** * Save registry diff */ -_PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename, struct reg_diff_callbacks **callbacks, void **callback_data) +_PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename, + struct reg_diff_callbacks **callbacks, + void **callback_data) { struct preg_data *data; struct { char hdr[4]; uint32_t version; } preg_header; - + data = talloc_zero(ctx, struct preg_data); *callback_data = data; @@ -105,23 +111,25 @@ _PUBLIC_ WERROR reg_preg_diff_save(TALLOC_CTX *ctx, const char *filename, struct } snprintf(preg_header.hdr, 4, "PReg"); SIVAL(&preg_header, 4, 1); - write(data->fd, (uint8_t *)&preg_header,8); + write(data->fd, (uint8_t *)&preg_header,8); *callbacks = talloc(ctx, struct reg_diff_callbacks); - + (*callbacks)->add_key = reg_preg_diff_add_key; (*callbacks)->del_key = reg_preg_diff_del_key; (*callbacks)->set_value = reg_preg_diff_set_value; (*callbacks)->del_value = reg_preg_diff_del_value; (*callbacks)->del_all_values = reg_preg_diff_del_all_values; (*callbacks)->done = reg_preg_diff_done; - + return WERR_OK; } /** * Load diff file */ -_PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *callbacks, void *callback_data) +_PUBLIC_ WERROR reg_preg_diff_load(int fd, + const struct reg_diff_callbacks *callbacks, + void *callback_data) { struct { char hdr[4]; @@ -131,7 +139,7 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *call char *buf_ptr = buf; TALLOC_CTX *mem_ctx = talloc_init("reg_preg_diff_load"); - + /* Read first 8 bytes (the header) */ if (read(fd, &preg_header, 8) != 8) { DEBUG(0, ("Could not read PReg file: %s\n", @@ -146,14 +154,14 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *call } if (preg_header.version > 1) { DEBUG(0, ("Warning: file format version is higher than expected.\n")); - } + } /* Read the entries */ while(1) { char *key, *value_name; uint32_t value_type, length; DATA_BLOB data; - + if (!W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr))) { break; } @@ -162,17 +170,19 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *call close(fd); return WERR_GENERAL_FAILURE; } - + /* Get the path */ buf_ptr = buf; - while (W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr != ';' && buf_ptr-buf < sizeof(buf)) { + while (W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && + *buf_ptr != ';' && buf_ptr-buf < sizeof(buf)) { buf_ptr++; } key = talloc_asprintf(mem_ctx, "\\%s", buf); - + /* Get the name */ buf_ptr = buf; - while (W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr != ';' && buf_ptr-buf < sizeof(buf)) { + while (W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && + *buf_ptr != ';' && buf_ptr-buf < sizeof(buf)) { buf_ptr++; } value_name = talloc_strdup(mem_ctx, buf); @@ -185,7 +195,8 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *call } /* Read past delimiter */ buf_ptr = buf; - if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr == ';') && buf_ptr-buf < sizeof(buf)) { + if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && + *buf_ptr == ';') && buf_ptr-buf < sizeof(buf)) { DEBUG(0, ("Error in PReg file.\n")); close(fd); return WERR_GENERAL_FAILURE; @@ -198,40 +209,43 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *call } /* Read past delimiter */ buf_ptr = buf; - if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr == ';') && buf_ptr-buf < sizeof(buf)) { + if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && + *buf_ptr == ';') && buf_ptr-buf < sizeof(buf)) { DEBUG(0, ("Error in PReg file.\n")); close(fd); return WERR_GENERAL_FAILURE; - } + } /* Get the data */ buf_ptr = buf; - if (length < sizeof(buf) && read(fd, buf_ptr, length) != length) { + if (length < sizeof(buf) && + read(fd, buf_ptr, length) != length) { DEBUG(0, ("Error while reading PReg\n")); close(fd); return WERR_GENERAL_FAILURE; } - data.length = length; - data.data = talloc_memdup(mem_ctx, buf, length); - + data = data_blob_talloc(mem_ctx, buf, length); + /* Check if delimiter is in place (whine if it isn't) */ buf_ptr = buf; - if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && *buf_ptr == ']') && buf_ptr-buf < sizeof(buf)) { - DEBUG(0, ("Warning: Missing ']' in PReg file, expected ']', got '%c' 0x%x.\n",*buf_ptr, *buf_ptr)); + if (!(W_ERROR_IS_OK(preg_read_utf16(fd, buf_ptr)) && + *buf_ptr == ']') && buf_ptr-buf < sizeof(buf)) { + DEBUG(0, ("Warning: Missing ']' in PReg file, expected ']', got '%c' 0x%x.\n", + *buf_ptr, *buf_ptr)); } if (strcasecmp(value_name, "**DelVals") == 0) { callbacks->del_all_values(callback_data, key); } else if (strncasecmp(value_name, "**Del.",6) == 0) { char *p = value_name+6; - + callbacks->del_value(callback_data, key, p); } else if (strcasecmp(value_name, "**DeleteValues") == 0) { char *p, *q; p = (char *) data.data; - + while ((q = strchr_m(p, ';'))) { - *q = '\0'; + *q = '\0'; q++; callbacks->del_value(callback_data, key, p); @@ -243,28 +257,30 @@ _PUBLIC_ WERROR reg_preg_diff_load(int fd, const struct reg_diff_callbacks *call char *p, *q, *full_key; p = (char *) data.data; - + while ((q = strchr_m(p, ';'))) { *q = '\0'; q++; - - full_key = talloc_asprintf(mem_ctx, "%s\\%s", key, p); + + full_key = talloc_asprintf(mem_ctx, "%s\\%s", + key, p); callbacks->del_key(callback_data, full_key); talloc_free(full_key); - p = q; + p = q; } full_key = talloc_asprintf(mem_ctx, "%s\\%s", key, p); callbacks->del_key(callback_data, full_key); talloc_free(full_key); } else { callbacks->add_key(callback_data, key); - callbacks->set_value(callback_data, key, value_name, value_type, data); + callbacks->set_value(callback_data, key, value_name, + value_type, data); } talloc_free(key); talloc_free(value_name); talloc_free(data.data); } - close(fd); + close(fd); return WERR_OK; } diff --git a/source4/lib/registry/regf.c b/source4/lib/registry/regf.c index d74ffd2b4b..2dd27ca33d 100644 --- a/source4/lib/registry/regf.c +++ b/source4/lib/registry/regf.c @@ -8,15 +8,15 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>. */ - + #include "includes.h" #include "lib/registry/hive.h" #include "system/filesys.h" @@ -28,7 +28,7 @@ static struct hive_operations reg_backend_regf; /** - * There are several places on the web where the REGF format is explained; + * There are several places on the web where the REGF format is explained; * * TODO: Links */ @@ -53,18 +53,18 @@ static WERROR regf_save_hbin(struct regf_data *data); struct regf_key_data { struct hive_key key; - struct regf_data *hive; + struct regf_data *hive; uint32_t offset; struct nk_block *nk; }; -static struct hbin_block *hbin_by_offset(const struct regf_data *data, - uint32_t offset, uint32_t *rel_offset) +static struct hbin_block *hbin_by_offset(const struct regf_data *data, + uint32_t offset, uint32_t *rel_offset) { int i; for (i = 0; data->hbins[i]; i++) { - if (offset >= data->hbins[i]->offset_from_first && + if (offset >= data->hbins[i]->offset_from_first && offset < data->hbins[i]->offset_from_first+ data->hbins[i]->offset_to_next) { if (rel_offset != NULL) @@ -84,7 +84,7 @@ static uint32_t regf_hdr_checksum(const uint8_t *buffer) { uint32_t checksum = 0, x; int i; - + for (i = 0; i < 0x01FB; i+= 4) { x = IVAL(buffer, i); checksum ^= x; @@ -122,14 +122,14 @@ static DATA_BLOB hbin_get(const struct regf_data *data, uint32_t offset) ret.length = (ret.length ^ 0xffffffff) + 1; ret.length -= 4; /* 4 bytes for the length... */ - ret.data = hbin->data + + ret.data = hbin->data + (offset - hbin->offset_from_first - 0x20) + 4; - + return ret; } -static bool hbin_get_tdr (struct regf_data *regf, uint32_t offset, - TALLOC_CTX *ctx, tdr_pull_fn_t pull_fn, void *p) +static bool hbin_get_tdr(struct regf_data *regf, uint32_t offset, + TALLOC_CTX *ctx, tdr_pull_fn_t pull_fn, void *p) { struct tdr_pull pull; @@ -140,9 +140,10 @@ static bool hbin_get_tdr (struct regf_data *regf, uint32_t offset, DEBUG(1, ("Unable to get data at 0x%04x\n", offset)); return false; } - + if (NT_STATUS_IS_ERR(pull_fn(&pull, ctx, p))) { - DEBUG(1, ("Error parsing record at 0x%04x using tdr\n", offset)); + DEBUG(1, ("Error parsing record at 0x%04x using tdr\n", + offset)); return false; } @@ -150,8 +151,8 @@ static bool hbin_get_tdr (struct regf_data *regf, uint32_t offset, } /* Allocate some new data */ -static DATA_BLOB hbin_alloc(struct regf_data *data, uint32_t size, - uint32_t *offset) +static DATA_BLOB hbin_alloc(struct regf_data *data, uint32_t size, + uint32_t *offset) { DATA_BLOB ret; uint32_t rel_offset = -1; /* Relative offset ! */ @@ -190,13 +191,15 @@ static DATA_BLOB hbin_alloc(struct regf_data *data, uint32_t size, my_size = -my_size; } else if (my_size == size) { /* exact match */ rel_offset = j; - DEBUG(4, ("Found free block of exact size %d in middle of HBIN\n", size)); + DEBUG(4, ("Found free block of exact size %d in middle of HBIN\n", + size)); break; } else if (my_size > size) { /* data will remain */ rel_offset = j; /* Split this block and mark the next block as free */ - SIVAL(hbin->data, rel_offset+size, my_size-size); - DEBUG(4, ("Found free block of size %d (needing %d) in middle of HBIN\n", my_size, size)); + SIVAL(hbin->data, rel_offset+size, my_size-size); + DEBUG(4, ("Found free block of size %d (needing %d) in middle of HBIN\n", + my_size, size)); break; } } @@ -204,12 +207,14 @@ static DATA_BLOB hbin_alloc(struct regf_data *data, uint32_t size, if (rel_offset != -1) break; } - - /* No space available in previous hbins, + + /* No space available in previous hbins, * allocate new one */ - if (data->hbins[i] == NULL) { - DEBUG(4, ("No space available in other HBINs for block of size %d, allocating new HBIN\n", size)); - data->hbins = talloc_realloc(data, data->hbins, struct hbin_block *, i+2); + if (data->hbins[i] == NULL) { + DEBUG(4, ("No space available in other HBINs for block of size %d, allocating new HBIN\n", + size)); + data->hbins = talloc_realloc(data, data->hbins, + struct hbin_block *, i+2); hbin = talloc(data->hbins, struct hbin_block); SMB_ASSERT(hbin != NULL); @@ -255,11 +260,12 @@ static uint32_t hbin_store (struct regf_data *data, DATA_BLOB blob) return ret; } -static uint32_t hbin_store_tdr (struct regf_data *data, tdr_push_fn_t push_fn, void *p) +static uint32_t hbin_store_tdr(struct regf_data *data, + tdr_push_fn_t push_fn, void *p) { struct tdr_push *push = talloc_zero(data, struct tdr_push); uint32_t ret; - + if (NT_STATUS_IS_ERR(push_fn(push, p))) { DEBUG(0, ("Error during push\n")); return -1; @@ -278,26 +284,27 @@ static void hbin_free (struct regf_data *data, uint32_t offset) { int32_t size; uint32_t rel_offset; - int32_t next_size; + int32_t next_size; struct hbin_block *hbin; SMB_ASSERT (offset > 0); - + hbin = hbin_by_offset(data, offset, &rel_offset); if (hbin == NULL) return; - + /* Get original size */ size = IVALS(hbin->data, rel_offset); if (size > 0) { - DEBUG(1, ("Trying to free already freed block at 0x%04x\n", offset)); + DEBUG(1, ("Trying to free already freed block at 0x%04x\n", + offset)); return; } /* Mark as unused */ size = -size; - + /* If the next block is free, merge into big free block */ if (rel_offset + size < hbin->offset_to_next) { next_size = IVALS(hbin->data, rel_offset+size); @@ -312,13 +319,14 @@ static void hbin_free (struct regf_data *data, uint32_t offset) /** * Store a data blob data was already stored, but has changed in size - * Will try to save it at the current location if possible, otherwise + * Will try to save it at the current location if possible, otherwise * does a free + store */ -static uint32_t hbin_store_resize(struct regf_data *data, - uint32_t orig_offset, DATA_BLOB blob) +static uint32_t hbin_store_resize(struct regf_data *data, + uint32_t orig_offset, DATA_BLOB blob) { uint32_t rel_offset; - struct hbin_block *hbin = hbin_by_offset(data, orig_offset, &rel_offset); + struct hbin_block *hbin = hbin_by_offset(data, orig_offset, + &rel_offset); int32_t my_size; int32_t orig_size; int32_t needed_size; @@ -343,7 +351,8 @@ static uint32_t hbin_store_resize(struct regf_data *data, * and free/merge it */ if (orig_size - needed_size > 0x4) { SIVALS(hbin->data, rel_offset, -needed_size); - SIVALS(hbin->data, rel_offset + needed_size, needed_size-orig_size); + SIVALS(hbin->data, rel_offset + needed_size, + needed_size-orig_size); hbin_free(data, orig_offset + needed_size); } return orig_offset; @@ -357,7 +366,7 @@ static uint32_t hbin_store_resize(struct regf_data *data, break; my_size = IVALS(hbin->data, i); - + if (my_size == 0x0) { DEBUG(0, ("Invalid zero-length block! File is corrupt.\n")); break; @@ -367,7 +376,8 @@ static uint32_t hbin_store_resize(struct regf_data *data, if (possible_size >= blob.length) { SIVAL(hbin->data, rel_offset, -possible_size); - memcpy(hbin->data + rel_offset + 0x4, blob.data, blob.length); + memcpy(hbin->data + rel_offset + 0x4, + blob.data, blob.length); return orig_offset; } } @@ -376,12 +386,13 @@ static uint32_t hbin_store_resize(struct regf_data *data, return hbin_store(data, blob); } -static uint32_t hbin_store_tdr_resize (struct regf_data *regf, tdr_push_fn_t push_fn, - uint32_t orig_offset, void *p) +static uint32_t hbin_store_tdr_resize(struct regf_data *regf, + tdr_push_fn_t push_fn, + uint32_t orig_offset, void *p) { struct tdr_push *push = talloc_zero(regf, struct tdr_push); uint32_t ret; - + if (NT_STATUS_IS_ERR(push_fn(push, p))) { DEBUG(0, ("Error during push\n")); return -1; @@ -394,13 +405,13 @@ static uint32_t hbin_store_tdr_resize (struct regf_data *regf, tdr_push_fn_t pus return ret; } -static uint32_t regf_create_lh_hash(const char *name) +static uint32_t regf_create_lh_hash(const char *name) { char *hash_name; uint32_t ret = 0; uint16_t i; - hash_name = strupper_talloc(NULL, name); + hash_name = strupper_talloc(NULL, name); for (i = 0; *(hash_name + i) != 0; i++) { ret *= 37; ret += *(hash_name + i); @@ -409,14 +420,14 @@ static uint32_t regf_create_lh_hash(const char *name) return ret; } -static WERROR regf_get_info (TALLOC_CTX *mem_ctx, - const struct hive_key *key, - const char **classname, - uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_mod_time) +static WERROR regf_get_info(TALLOC_CTX *mem_ctx, + const struct hive_key *key, + const char **classname, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_mod_time) { - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)key; if (num_subkeys != NULL) @@ -427,22 +438,23 @@ static WERROR regf_get_info (TALLOC_CTX *mem_ctx, if (classname != NULL) { if (private_data->nk->clsname_offset != -1) { - DATA_BLOB data = hbin_get(private_data->hive, - private_data->nk->clsname_offset); - *classname = talloc_strndup(mem_ctx, - (char*)data.data, private_data->nk->clsname_length); - } else + DATA_BLOB data = hbin_get(private_data->hive, + private_data->nk->clsname_offset); + *classname = talloc_strndup(mem_ctx, + (char*)data.data, + private_data->nk->clsname_length); + } else *classname = NULL; } /* TODO: Last mod time */ - + return WERR_OK; } -static struct regf_key_data *regf_get_key(TALLOC_CTX *ctx, - struct regf_data *regf, - uint32_t offset) +static struct regf_key_data *regf_get_key(TALLOC_CTX *ctx, + struct regf_data *regf, + uint32_t offset) { struct nk_block *nk; struct regf_key_data *ret; @@ -457,7 +469,8 @@ static struct regf_key_data *regf_get_key(TALLOC_CTX *ctx, ret->nk = nk; - if (!hbin_get_tdr(regf, offset, nk, (tdr_pull_fn_t)tdr_pull_nk_block, nk)) { + if (!hbin_get_tdr(regf, offset, nk, + (tdr_pull_fn_t)tdr_pull_nk_block, nk)) { DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset)); return NULL; } @@ -472,11 +485,11 @@ static struct regf_key_data *regf_get_key(TALLOC_CTX *ctx, } -static WERROR regf_get_value(TALLOC_CTX *ctx, const struct hive_key *key, - int idx, const char **name, - uint32_t *data_type, DATA_BLOB *data) +static WERROR regf_get_value(TALLOC_CTX *ctx, const struct hive_key *key, + int idx, const char **name, + uint32_t *data_type, DATA_BLOB *data) { - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)key; struct vk_block *vk; struct regf_data *regf = private_data->hive; @@ -500,8 +513,9 @@ static WERROR regf_get_value(TALLOC_CTX *ctx, const struct hive_key *key, vk = talloc(NULL, struct vk_block); W_ERROR_HAVE_NO_MEMORY(vk); - - if (!hbin_get_tdr(regf, vk_offset, vk, (tdr_pull_fn_t)tdr_pull_vk_block, vk)) { + + if (!hbin_get_tdr(regf, vk_offset, vk, + (tdr_pull_fn_t)tdr_pull_vk_block, vk)) { DEBUG(0, ("Unable to get VK block at %d\n", vk_offset)); talloc_free(vk); return WERR_GENERAL_FAILURE; @@ -514,7 +528,7 @@ static WERROR regf_get_value(TALLOC_CTX *ctx, const struct hive_key *key, if (data_type != NULL) *data_type = vk->data_type; - if (vk->data_length & 0x80000000) { + if (vk->data_length & 0x80000000) { vk->data_length &=~0x80000000; data->data = (uint8_t *)&vk->data_offset; data->length = vk->data_length; @@ -527,13 +541,13 @@ static WERROR regf_get_value(TALLOC_CTX *ctx, const struct hive_key *key, } talloc_free(vk); - + return WERR_OK; } -static WERROR regf_get_value_by_name (TALLOC_CTX *mem_ctx, - struct hive_key *key, const char *name, - uint32_t *type, DATA_BLOB *data) +static WERROR regf_get_value_by_name(TALLOC_CTX *mem_ctx, + struct hive_key *key, const char *name, + uint32_t *type, DATA_BLOB *data) { int i; const char *vname; @@ -541,24 +555,25 @@ static WERROR regf_get_value_by_name (TALLOC_CTX *mem_ctx, /* FIXME: Do binary search? Is this list sorted at all? */ - for (i = 0; W_ERROR_IS_OK(error = regf_get_value(mem_ctx, key, i, - &vname, type, data)); i++) { + for (i = 0; W_ERROR_IS_OK(error = regf_get_value(mem_ctx, key, i, + &vname, type, data)); + i++) { if (!strcmp(vname, name)) return WERR_OK; - } + } if (W_ERROR_EQUAL(error, WERR_NO_MORE_ITEMS)) return WERR_NOT_FOUND; return error; } - -static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, - const struct hive_key *key, - uint32_t idx, const char **name, - const char **classname, - NTTIME *last_mod_time) + +static WERROR regf_get_subkey_by_index(TALLOC_CTX *ctx, + const struct hive_key *key, + uint32_t idx, const char **name, + const char **classname, + NTTIME *last_mod_time) { DATA_BLOB data; struct regf_key_data *ret; @@ -594,7 +609,7 @@ static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, return WERR_GENERAL_FAILURE; } key_off = li.nk_offset[idx]; - + } else if (!strncmp((char *)data.data, "lf", 2)) { struct lf_block lf; struct tdr_pull pull; @@ -618,17 +633,17 @@ static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, } else if (!strncmp((char *)data.data, "lh", 2)) { struct lh_block lh; struct tdr_pull pull; - + DEBUG(10, ("Subkeys in LH list\n")); ZERO_STRUCT(pull); pull.data = data; - + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { DEBUG(0, ("Error parsing LH list\n")); return WERR_GENERAL_FAILURE; } SMB_ASSERT(!strncmp(lh.header, "lh", 2)); - + if (lh.key_count != nk->num_subkeys) { DEBUG(0, ("Subkey counts don't match\n")); return WERR_GENERAL_FAILURE; @@ -639,41 +654,43 @@ static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, struct tdr_pull pull; uint16_t i; uint16_t sublist_count = 0; - + DEBUG(10, ("Subkeys in RI list\n")); ZERO_STRUCT(pull); pull.data = data; - + if (NT_STATUS_IS_ERR(tdr_pull_ri_block(&pull, nk, &ri))) { DEBUG(0, ("Error parsing RI list\n")); return WERR_GENERAL_FAILURE; } SMB_ASSERT(!strncmp(ri.header, "ri", 2)); - + for (i = 0; i < ri.key_count; i++) { DATA_BLOB list_data; - + /* Get sublist data blob */ list_data = hbin_get(private_data->hive, ri.offset[i]); if (!list_data.data) { DEBUG(0, ("Error getting RI list.")); return WERR_GENERAL_FAILURE; } - + ZERO_STRUCT(pull); pull.data = list_data; - + if (!strncmp((char *)list_data.data, "li", 2)) { struct li_block li; DEBUG(10, ("Subkeys in RI->LI list\n")); - if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, + nk, + &li))) { DEBUG(0, ("Error parsing LI list from RI\n")); return WERR_GENERAL_FAILURE; } SMB_ASSERT(!strncmp(li.header, "li", 2)); - + /* Advance to next sublist if necessary */ if (idx >= sublist_count + li.key_count) { sublist_count += li.key_count; @@ -684,10 +701,12 @@ static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, break; } else if (!strncmp((char *)list_data.data, "lh", 2)) { struct lh_block lh; - + DEBUG(10, ("Subkeys in RI->LH list\n")); - if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, + nk, + &lh))) { DEBUG(0, ("Error parsing LH list from RI\n")); return WERR_GENERAL_FAILURE; } @@ -706,15 +725,15 @@ static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, return WERR_GENERAL_FAILURE; } - + } - + if (idx > sublist_count) { return WERR_NO_MORE_ITEMS; } } else { - DEBUG(0, ("Unknown type for subkey list (0x%04x): %c%c\n", + DEBUG(0, ("Unknown type for subkey list (0x%04x): %c%c\n", nk->subkeys_offset, data.data[0], data.data[1])); return WERR_GENERAL_FAILURE; } @@ -723,11 +742,12 @@ static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, if (classname != NULL) { if (ret->nk->clsname_offset != -1) { - DATA_BLOB db = hbin_get(ret->hive, - ret->nk->clsname_offset); - *classname = talloc_strndup(ctx, - (char*)db.data, ret->nk->clsname_length); - } else + DATA_BLOB db = hbin_get(ret->hive, + ret->nk->clsname_offset); + *classname = talloc_strndup(ctx, + (char*)db.data, + ret->nk->clsname_length); + } else *classname = NULL; } @@ -742,16 +762,17 @@ static WERROR regf_get_subkey_by_index (TALLOC_CTX *ctx, return WERR_OK; } -static WERROR regf_match_subkey_by_name(TALLOC_CTX *ctx, - const struct hive_key *key, uint32_t offset, - const char *name, uint32_t *ret) +static WERROR regf_match_subkey_by_name(TALLOC_CTX *ctx, + const struct hive_key *key, + uint32_t offset, + const char *name, uint32_t *ret) { DATA_BLOB subkey_data; struct nk_block subkey; struct tdr_pull pull; - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)key; - + subkey_data = hbin_get(private_data->hive, offset); if (!subkey_data.data) { DEBUG(0, ("Unable to retrieve subkey HBIN\n")); @@ -760,7 +781,7 @@ static WERROR regf_match_subkey_by_name(TALLOC_CTX *ctx, ZERO_STRUCT(pull); pull.data = subkey_data; - + if (NT_STATUS_IS_ERR(tdr_pull_nk_block(&pull, ctx, &subkey))) { DEBUG(0, ("Error parsing NK structure.\n")); return WERR_GENERAL_FAILURE; @@ -778,14 +799,14 @@ static WERROR regf_match_subkey_by_name(TALLOC_CTX *ctx, } return WERR_OK; } - -static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, - const struct hive_key *key, - const char *name, - struct hive_key **ret) + +static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, + const struct hive_key *key, + const char *name, + struct hive_key **ret) { DATA_BLOB data; - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)key; struct nk_block *nk = private_data->nk; uint32_t key_off = 0; @@ -804,7 +825,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, DEBUG(10, ("Subkeys in LI list\n")); ZERO_STRUCT(pull); pull.data = data; - + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { DEBUG(0, ("Error parsing LI list\n")); return WERR_GENERAL_FAILURE; @@ -815,9 +836,12 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, DEBUG(0, ("Subkey counts don't match\n")); return WERR_GENERAL_FAILURE; } - + for (i = 0; i < li.key_count; i++) { - W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, li.nk_offset[i], name, &key_off)); + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, + li.nk_offset[i], + name, + &key_off)); if (key_off != 0) break; } @@ -831,7 +855,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, DEBUG(10, ("Subkeys in LF list\n")); ZERO_STRUCT(pull); pull.data = data; - + if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, nk, &lf))) { DEBUG(0, ("Error parsing LF list\n")); return WERR_GENERAL_FAILURE; @@ -842,12 +866,16 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, DEBUG(0, ("Subkey counts don't match\n")); return WERR_GENERAL_FAILURE; } - + for (i = 0; i < lf.key_count; i++) { if (strncmp(lf.hr[i].hash, name, 4)) { continue; } - W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, lf.hr[i].nk_offset, name, &key_off)); + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, + key, + lf.hr[i].nk_offset, + name, + &key_off)); if (key_off != 0) break; } @@ -862,7 +890,7 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, DEBUG(10, ("Subkeys in LH list\n")); ZERO_STRUCT(pull); pull.data = data; - + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { DEBUG(0, ("Error parsing LH list\n")); return WERR_GENERAL_FAILURE; @@ -873,16 +901,20 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, DEBUG(0, ("Subkey counts don't match\n")); return WERR_GENERAL_FAILURE; } - + hash = regf_create_lh_hash(name); for (i = 0; i < lh.key_count; i++) { if (lh.hr[i].base37 != hash) { continue; } - W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, lh.hr[i].nk_offset, name, &key_off)); + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, + key, + lh.hr[i].nk_offset, + name, + &key_off)); if (key_off != 0) break; - } + } if (key_off == 0) return WERR_NOT_FOUND; } else if (!strncmp((char *)data.data, "ri", 2)) { @@ -893,46 +925,52 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, DEBUG(10, ("Subkeys in RI list\n")); ZERO_STRUCT(pull); pull.data = data; - + if (NT_STATUS_IS_ERR(tdr_pull_ri_block(&pull, nk, &ri))) { DEBUG(0, ("Error parsing RI list\n")); return WERR_GENERAL_FAILURE; } SMB_ASSERT(!strncmp(ri.header, "ri", 2)); - + for (i = 0; i < ri.key_count; i++) { DATA_BLOB list_data; - + /* Get sublist data blob */ list_data = hbin_get(private_data->hive, ri.offset[i]); if (list_data.data == NULL) { DEBUG(0, ("Error getting RI list.")); return WERR_GENERAL_FAILURE; } - + ZERO_STRUCT(pull); pull.data = list_data; - + if (!strncmp((char *)list_data.data, "li", 2)) { struct li_block li; - - if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, nk, &li))) { + + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, + nk, + &li))) { DEBUG(0, ("Error parsing LI list from RI\n")); return WERR_GENERAL_FAILURE; } SMB_ASSERT(!strncmp(li.header, "li", 2)); - + for (j = 0; j < li.key_count; j++) { - W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, - li.nk_offset[j], name, &key_off)); + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, + li.nk_offset[j], + name, + &key_off)); if (key_off) break; } } else if (!strncmp((char *)list_data.data, "lh", 2)) { struct lh_block lh; uint32_t hash; - - if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, nk, &lh))) { + + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, + nk, + &lh))) { DEBUG(0, ("Error parsing LH list from RI\n")); return WERR_GENERAL_FAILURE; } @@ -943,8 +981,10 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, if (lh.hr[j].base37 != hash) { continue; } - W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, - lh.hr[j].nk_offset, name, &key_off)); + W_ERROR_NOT_OK_RETURN(regf_match_subkey_by_name(nk, key, + lh.hr[j].nk_offset, + name, + &key_off)); if (key_off) break; } @@ -959,14 +999,15 @@ static WERROR regf_get_subkey_by_name(TALLOC_CTX *ctx, return WERR_GENERAL_FAILURE; } - *ret = (struct hive_key *)regf_get_key (ctx, private_data->hive, key_off); + *ret = (struct hive_key *)regf_get_key(ctx, private_data->hive, + key_off); return WERR_OK; } -static WERROR regf_set_sec_desc (struct hive_key *key, - const struct security_descriptor *sec_desc) +static WERROR regf_set_sec_desc(struct hive_key *key, + const struct security_descriptor *sec_desc) { - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)key; struct sk_block cur_sk, sk, new_sk; struct regf_data *regf = private_data->hive; @@ -976,47 +1017,51 @@ static WERROR regf_set_sec_desc (struct hive_key *key, bool update_cur_sk = false; /* Get the root nk */ - hbin_get_tdr(regf, regf->header->data_offset, regf, - (tdr_pull_fn_t) tdr_pull_nk_block, &root); + hbin_get_tdr(regf, regf->header->data_offset, regf, + (tdr_pull_fn_t) tdr_pull_nk_block, &root); /* Push the security descriptor to a blob */ - if (NT_STATUS_IS_ERR(ndr_push_struct_blob(&data, regf, sec_desc, - (ndr_push_flags_fn_t)ndr_push_security_descriptor))) { + if (NT_STATUS_IS_ERR(ndr_push_struct_blob(&data, regf, sec_desc, + (ndr_push_flags_fn_t)ndr_push_security_descriptor))) { DEBUG(0, ("Unable to push security descriptor\n")); return WERR_GENERAL_FAILURE; } - /* Get the current security descriptor for the key */ - if (!hbin_get_tdr(regf, private_data->nk->sk_offset, regf, - (tdr_pull_fn_t) tdr_pull_sk_block, &cur_sk)) { + /* Get the current security descriptor for the key */ + if (!hbin_get_tdr(regf, private_data->nk->sk_offset, regf, + (tdr_pull_fn_t) tdr_pull_sk_block, &cur_sk)) { DEBUG(0, ("Unable to find security descriptor for current key\n")); return WERR_BADFILE; } /* If there's no change, change nothing. */ - if (memcmp(data.data, cur_sk.sec_desc, MIN(data.length, cur_sk.rec_size)) == 0) { + if (memcmp(data.data, cur_sk.sec_desc, + MIN(data.length, cur_sk.rec_size)) == 0) { return WERR_OK; } - /* Delete the current sk if only this key is using it */ + /* Delete the current sk if only this key is using it */ if (cur_sk.ref_cnt == 1) { - /* Get the previous security descriptor for the key */ - if (!hbin_get_tdr(regf, cur_sk.prev_offset, regf, - (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + /* Get the previous security descriptor for the key */ + if (!hbin_get_tdr(regf, cur_sk.prev_offset, regf, + (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find prev security descriptor for current key\n")); return WERR_BADFILE; } /* Change and store the previous security descriptor */ sk.next_offset = cur_sk.next_offset; - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, cur_sk.prev_offset, &sk); - - /* Get the next security descriptor for the key */ - if (!hbin_get_tdr(regf, cur_sk.next_offset, regf, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, + cur_sk.prev_offset, &sk); + + /* Get the next security descriptor for the key */ + if (!hbin_get_tdr(regf, cur_sk.next_offset, regf, + (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find next security descriptor for current key\n")); return WERR_BADFILE; } /* Change and store the next security descriptor */ sk.prev_offset = cur_sk.prev_offset; - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, cur_sk.next_offset, &sk); + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, + cur_sk.next_offset, &sk); hbin_free(regf, private_data->nk->sk_offset); } else { @@ -1029,20 +1074,26 @@ static WERROR regf_set_sec_desc (struct hive_key *key, do { cur_sk_offset = sk_offset; - if (!hbin_get_tdr(regf, sk_offset, regf, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + if (!hbin_get_tdr(regf, sk_offset, regf, + (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find security descriptor\n")); return WERR_BADFILE; } if (memcmp(data.data, sk.sec_desc, MIN(data.length, sk.rec_size)) == 0) { private_data->nk->sk_offset = sk_offset; sk.ref_cnt++; - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, sk_offset, &sk); - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, private_data->offset, private_data->nk); + hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_sk_block, + sk_offset, &sk); + hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_nk_block, + private_data->offset, + private_data->nk); return WERR_OK; } sk_offset = sk.next_offset; } while (sk_offset != root.sk_offset); - + ZERO_STRUCT(new_sk); new_sk.header = "sk"; new_sk.prev_offset = cur_sk_offset; @@ -1050,8 +1101,10 @@ static WERROR regf_set_sec_desc (struct hive_key *key, new_sk.ref_cnt = 1; new_sk.rec_size = data.length; new_sk.sec_desc = data.data; - - sk_offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_sk_block, &new_sk); + + sk_offset = hbin_store_tdr(regf, + (tdr_push_fn_t) tdr_push_sk_block, + &new_sk); if (sk_offset == -1) { DEBUG(0, ("Error storing sk block\n")); return WERR_GENERAL_FAILURE; @@ -1059,47 +1112,58 @@ static WERROR regf_set_sec_desc (struct hive_key *key, private_data->nk->sk_offset = sk_offset; if (update_cur_sk) { - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, private_data->nk->sk_offset, &cur_sk); + hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_sk_block, + private_data->nk->sk_offset, &cur_sk); } - /* Get the previous security descriptor for the key */ - if (!hbin_get_tdr(regf, new_sk.prev_offset, regf, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + /* Get the previous security descriptor for the key */ + if (!hbin_get_tdr(regf, new_sk.prev_offset, regf, + (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find security descriptor for previous key\n")); return WERR_BADFILE; } /* Change and store the previous security descriptor */ sk.next_offset = sk_offset; - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, cur_sk.prev_offset, &sk); - - /* Get the next security descriptor for the key (always root, as we append) */ - if (!hbin_get_tdr(regf, new_sk.next_offset, regf, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_sk_block, + cur_sk.prev_offset, &sk); + + /* Get the next security descriptor for the key (always root, as we append) */ + if (!hbin_get_tdr(regf, new_sk.next_offset, regf, + (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find security descriptor for current key\n")); return WERR_BADFILE; } /* Change and store the next security descriptor (always root, as we append) */ sk.prev_offset = sk_offset; - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, root.sk_offset, &sk); + hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_sk_block, + root.sk_offset, &sk); /* Store the nk. */ - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_sk_block, private_data->offset, private_data->nk); + hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_sk_block, + private_data->offset, private_data->nk); return WERR_OK; } -static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct hive_key *key, - struct security_descriptor **sd) +static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct hive_key *key, + struct security_descriptor **sd) { - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)key; struct sk_block sk; struct regf_data *regf = private_data->hive; DATA_BLOB data; - if (!hbin_get_tdr(regf, private_data->nk->sk_offset, ctx, (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { + if (!hbin_get_tdr(regf, private_data->nk->sk_offset, ctx, + (tdr_pull_fn_t) tdr_pull_sk_block, &sk)) { DEBUG(0, ("Unable to find security descriptor\n")); return WERR_GENERAL_FAILURE; } - + if (strcmp(sk.header, "sk") != 0) { DEBUG(0, ("Expected 'sk', got '%s'\n", sk.header)); return WERR_GENERAL_FAILURE; @@ -1110,7 +1174,8 @@ static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct hive_key *key, data.data = sk.sec_desc; data.length = sk.rec_size; - if (NT_STATUS_IS_ERR(ndr_pull_struct_blob(&data, ctx, *sd, (ndr_pull_flags_fn_t)ndr_pull_security_descriptor))) { + if (NT_STATUS_IS_ERR(ndr_pull_struct_blob(&data, ctx, *sd, + (ndr_pull_flags_fn_t)ndr_pull_security_descriptor))) { DEBUG(0, ("Error parsing security descriptor\n")); return WERR_GENERAL_FAILURE; } @@ -1118,45 +1183,51 @@ static WERROR regf_get_sec_desc(TALLOC_CTX *ctx, const struct hive_key *key, return WERR_OK; } -static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, - const char *name, uint32_t key_offset, uint32_t *ret) +static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, + const char *name, + uint32_t key_offset, uint32_t *ret) { DATA_BLOB data; /* Create a new key if necessary */ - if (list_offset == -1) { + if (list_offset == -1) { if (regf->header->version.major != 1) { DEBUG(0, ("Can't store keys in unknown registry format\n")); return WERR_NOT_SUPPORTED; } - if (regf->header->version.minor < 3) { + if (regf->header->version.minor < 3) { /* Store LI */ struct li_block li; ZERO_STRUCT(li); li.header = "li"; - li.key_count = 1; + li.key_count = 1; li.nk_offset = talloc_array(regf, uint32_t, 1); W_ERROR_HAVE_NO_MEMORY(li.nk_offset); li.nk_offset[0] = key_offset; - *ret = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_li_block, &li); + *ret = hbin_store_tdr(regf, + (tdr_push_fn_t) tdr_push_li_block, + &li); talloc_free(li.nk_offset); - } else if (regf->header->version.minor == 3 || regf->header->version.minor == 4) { + } else if (regf->header->version.minor == 3 || + regf->header->version.minor == 4) { /* Store LF */ struct lf_block lf; ZERO_STRUCT(lf); lf.header = "lf"; lf.key_count = 1; - + lf.hr = talloc_array(regf, struct hash_record, 1); W_ERROR_HAVE_NO_MEMORY(lf.hr); lf.hr[0].nk_offset = key_offset; lf.hr[0].hash = talloc_strndup(lf.hr, name, 4); W_ERROR_HAVE_NO_MEMORY(lf.hr[0].hash); - *ret = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_lf_block, &lf); + *ret = hbin_store_tdr(regf, + (tdr_push_fn_t) tdr_push_lf_block, + &lf); talloc_free(lf.hr); } else if (regf->header->version.minor == 5) { @@ -1165,19 +1236,21 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, ZERO_STRUCT(lh); lh.header = "lh"; lh.key_count = 1; - + lh.hr = talloc_array(regf, struct lh_hash, 1); W_ERROR_HAVE_NO_MEMORY(lh.hr); lh.hr[0].nk_offset = key_offset; lh.hr[0].base37 = regf_create_lh_hash(name); - *ret = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_lh_block, &lh); + *ret = hbin_store_tdr(regf, + (tdr_push_fn_t) tdr_push_lh_block, + &lh); talloc_free(lh.hr); } return WERR_OK; - } - + } + data = hbin_get(regf, list_offset); if (!data.data) { DEBUG(0, ("Unable to find subkey list\n")); @@ -1187,7 +1260,7 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, if (!strncmp((char *)data.data, "li", 2)) { struct tdr_pull pull; struct li_block li; - + ZERO_STRUCT(pull); pull.data = data; @@ -1201,13 +1274,16 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, DEBUG(0, ("LI header corrupt\n")); return WERR_BADFILE; } - - li.nk_offset = talloc_realloc(regf, li.nk_offset, uint32_t, li.key_count+1); + + li.nk_offset = talloc_realloc(regf, li.nk_offset, + uint32_t, li.key_count+1); W_ERROR_HAVE_NO_MEMORY(li.nk_offset); li.nk_offset[li.key_count] = key_offset; li.key_count++; - *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_li_block, list_offset, &li); - + *ret = hbin_store_tdr_resize(regf, + (tdr_push_fn_t)tdr_push_li_block, + list_offset, &li); + talloc_free(li.nk_offset); } else if (!strncmp((char *)data.data, "lf", 2)) { struct tdr_pull pull; @@ -1221,14 +1297,17 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, return WERR_BADFILE; } SMB_ASSERT(!strncmp(lf.header, "lf", 2)); - - lf.hr = talloc_realloc(regf, lf.hr, struct hash_record, lf.key_count+1); + + lf.hr = talloc_realloc(regf, lf.hr, struct hash_record, + lf.key_count+1); W_ERROR_HAVE_NO_MEMORY(lf.hr); lf.hr[lf.key_count].nk_offset = key_offset; lf.hr[lf.key_count].hash = talloc_strndup(lf.hr, name, 4); W_ERROR_HAVE_NO_MEMORY(lf.hr[lf.key_count].hash); lf.key_count++; - *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_lf_block, list_offset, &lf); + *ret = hbin_store_tdr_resize(regf, + (tdr_push_fn_t)tdr_push_lf_block, + list_offset, &lf); talloc_free(lf.hr); } else if (!strncmp((char *)data.data, "lh", 2)) { @@ -1243,13 +1322,16 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, return WERR_BADFILE; } SMB_ASSERT(!strncmp(lh.header, "lh", 2)); - - lh.hr = talloc_realloc(regf, lh.hr, struct lh_hash, lh.key_count+1); + + lh.hr = talloc_realloc(regf, lh.hr, struct lh_hash, + lh.key_count+1); W_ERROR_HAVE_NO_MEMORY(lh.hr); lh.hr[lh.key_count].nk_offset = key_offset; lh.hr[lh.key_count].base37 = regf_create_lh_hash(name); lh.key_count++; - *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t)tdr_push_lh_block, list_offset, &lh); + *ret = hbin_store_tdr_resize(regf, + (tdr_push_fn_t)tdr_push_lh_block, + list_offset, &lh); talloc_free(lh.hr); } else if (!strncmp((char *)data.data, "ri", 2)) { @@ -1260,12 +1342,12 @@ static WERROR regf_sl_add_entry(struct regf_data *regf, uint32_t list_offset, DEBUG(0, ("Cannot add to unknown subkey list\n")); return WERR_BADFILE; } - + return WERR_OK; } -static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, - uint32_t key_offset, uint32_t *ret) +static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, + uint32_t key_offset, uint32_t *ret) { DATA_BLOB data; @@ -1280,17 +1362,17 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, struct tdr_pull pull; uint16_t i; bool found_offset = false; - + DEBUG(10, ("Subkeys in LI list\n")); - + ZERO_STRUCT(pull); - pull.data = data; - + pull.data = data; + if (NT_STATUS_IS_ERR(tdr_pull_li_block(&pull, regf, &li))) { DEBUG(0, ("Error parsing LI list\n")); return WERR_BADFILE; } - + SMB_ASSERT(!strncmp(li.header, "li", 2)); for (i = 0; i < li.key_count; i++) { @@ -1315,23 +1397,25 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, } /* Store li block */ - *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_li_block, list_offset, &li); + *ret = hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_li_block, + list_offset, &li); } else if (strncmp((char *)data.data, "lf", 2) == 0) { struct lf_block lf; struct tdr_pull pull; uint16_t i; bool found_offset = false; - + DEBUG(10, ("Subkeys in LF list\n")); - + ZERO_STRUCT(pull); - pull.data = data; - + pull.data = data; + if (NT_STATUS_IS_ERR(tdr_pull_lf_block(&pull, regf, &lf))) { DEBUG(0, ("Error parsing LF list\n")); return WERR_BADFILE; } - + SMB_ASSERT(!strncmp(lf.header, "lf", 2)); for (i = 0; i < lf.key_count; i++) { @@ -1349,7 +1433,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, return WERR_NOT_FOUND; } lf.key_count--; - + /* If the there are no entries left, free the subkey list */ if (lf.key_count == 0) { hbin_free(regf, list_offset); @@ -1358,23 +1442,25 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, } /* Store lf block */ - *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_lf_block, list_offset, &lf); + *ret = hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_lf_block, + list_offset, &lf); } else if (strncmp((char *)data.data, "lh", 2) == 0) { struct lh_block lh; struct tdr_pull pull; uint16_t i; bool found_offset = false; - + DEBUG(10, ("Subkeys in LH list\n")); - + ZERO_STRUCT(pull); - pull.data = data; - + pull.data = data; + if (NT_STATUS_IS_ERR(tdr_pull_lh_block(&pull, regf, &lh))) { DEBUG(0, ("Error parsing LF list\n")); return WERR_BADFILE; } - + SMB_ASSERT(!strncmp(lh.header, "lh", 2)); for (i = 0; i < lh.key_count; i++) { @@ -1392,7 +1478,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, return WERR_NOT_FOUND; } lh.key_count--; - + /* If the there are no entries left, free the subkey list */ if (lh.key_count == 0) { hbin_free(regf, list_offset); @@ -1401,7 +1487,9 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, } /* Store lh block */ - *ret = hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_lh_block, list_offset, &lh); + *ret = hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_lh_block, + list_offset, &lh); } else if (strncmp((char *)data.data, "ri", 2) == 0) { /* FIXME */ DEBUG(0, ("Sorry, deletion from ri block is not supported yet.\n")); @@ -1415,7 +1503,7 @@ static WERROR regf_sl_del_entry(struct regf_data *regf, uint32_t list_offset, static WERROR regf_del_value (struct hive_key *key, const char *name) { - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)key; struct regf_data *regf = private_data->hive; struct nk_block *nk = private_data->nk; @@ -1436,11 +1524,13 @@ static WERROR regf_del_value (struct hive_key *key, const char *name) ((uint32_t *)values.data)[i-1] = ((uint32_t *) values.data)[i]; } else { vk_offset = IVAL(values.data, i * 4); - if (!hbin_get_tdr(regf, vk_offset, private_data, - (tdr_pull_fn_t)tdr_pull_vk_block, &vk)) { - DEBUG(0, ("Unable to get VK block at %d\n", vk_offset)); + if (!hbin_get_tdr(regf, vk_offset, private_data, + (tdr_pull_fn_t)tdr_pull_vk_block, + &vk)) { + DEBUG(0, ("Unable to get VK block at %d\n", + vk_offset)); return WERR_BADFILE; - } + } if (strcmp(vk.data_name, name) == 0) { hbin_free(regf, vk_offset); found_offset = true; @@ -1458,10 +1548,13 @@ static WERROR regf_del_value (struct hive_key *key, const char *name) if (nk->num_values == 0) { hbin_free(regf, nk->values_offset); nk->values_offset = -1; - } else { - nk->values_offset = hbin_store_resize(regf, nk->values_offset, values); + } else { + nk->values_offset = hbin_store_resize(regf, + nk->values_offset, + values); } - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, private_data->offset, nk); + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, + private_data->offset, nk); return regf_save_hbin(private_data->hive); } @@ -1469,14 +1562,14 @@ static WERROR regf_del_value (struct hive_key *key, const char *name) static WERROR regf_del_key(const struct hive_key *parent, const char *name) { - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)parent; struct regf_key_data *key; struct nk_block *parent_nk; WERROR error; SMB_ASSERT(private_data); - + parent_nk = private_data->nk; if (parent_nk->subkeys_offset == -1) { @@ -1485,21 +1578,21 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name) } /* Find the key */ - if (!W_ERROR_IS_OK(regf_get_subkey_by_name(parent_nk, parent, name, - (struct hive_key **)&key))) { + if (!W_ERROR_IS_OK(regf_get_subkey_by_name(parent_nk, parent, name, + (struct hive_key **)&key))) { DEBUG(2, ("Key '%s' not found\n", name)); return WERR_NOT_FOUND; } - - if (key->nk->subkeys_offset != -1 || + + if (key->nk->subkeys_offset != -1 || key->nk->values_offset != -1) { DEBUG(0, ("Key '%s' is not empty.\n", name)); return WERR_FILE_EXISTS; } - + /* Delete it from the subkey list. */ - error = regf_sl_del_entry(private_data->hive, parent_nk->subkeys_offset, - key->offset, &parent_nk->subkeys_offset); + error = regf_sl_del_entry(private_data->hive, parent_nk->subkeys_offset, + key->offset, &parent_nk->subkeys_offset); if (!W_ERROR_IS_OK(error)) { DEBUG(0, ("Can't store new subkey list for parent key. Won't delete.\n")); return error; @@ -1507,9 +1600,9 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name) /* Re-store parent key */ parent_nk->num_subkeys--; - hbin_store_tdr_resize(private_data->hive, - (tdr_push_fn_t) tdr_push_nk_block, - private_data->offset, parent_nk); + hbin_store_tdr_resize(private_data->hive, + (tdr_push_fn_t) tdr_push_nk_block, + private_data->offset, parent_nk); if (key->nk->clsname_offset != -1) { hbin_free(private_data->hive, key->nk->clsname_offset); @@ -1519,12 +1612,12 @@ static WERROR regf_del_key(const struct hive_key *parent, const char *name) return regf_save_hbin(private_data->hive); } -static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent, - const char *name, const char *classname, - struct security_descriptor *sec_desc, - struct hive_key **ret) +static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent, + const char *name, const char *classname, + struct security_descriptor *sec_desc, + struct hive_key **ret) { - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)parent; struct nk_block *parent_nk = private_data->nk, nk; struct nk_block *root; @@ -1547,32 +1640,33 @@ static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent, nk.clsname_offset = -1; /* FIXME: fill in */ nk.clsname_length = 0; nk.key_name = name; - + /* Get the security descriptor of the root key */ root = talloc_zero(ctx, struct nk_block); W_ERROR_HAVE_NO_MEMORY(root); - if (!hbin_get_tdr(regf, regf->header->data_offset, root, - (tdr_pull_fn_t)tdr_pull_nk_block, root)) { + if (!hbin_get_tdr(regf, regf->header->data_offset, root, + (tdr_pull_fn_t)tdr_pull_nk_block, root)) { DEBUG(0, ("Unable to find HBIN data for offset %d\n", offset)); return WERR_GENERAL_FAILURE; } nk.sk_offset = root->sk_offset; talloc_free(root); - + /* Store the new nk key */ offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_nk_block, &nk); - - error = regf_sl_add_entry(regf, parent_nk->subkeys_offset, name, offset, &parent_nk->subkeys_offset); + + error = regf_sl_add_entry(regf, parent_nk->subkeys_offset, name, offset, + &parent_nk->subkeys_offset); if (!W_ERROR_IS_OK(error)) { hbin_free(regf, offset); return error; } - + parent_nk->num_subkeys++; /* Since the subkey offset of the parent can change, store it again */ - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, + hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, nk.parent_offset, parent_nk); *ret = (struct hive_key *)regf_get_key(ctx, regf, offset); @@ -1580,10 +1674,10 @@ static WERROR regf_add_key(TALLOC_CTX *ctx, const struct hive_key *parent, return regf_save_hbin(private_data->hive); } -static WERROR regf_set_value(struct hive_key *key, const char *name, - uint32_t type, const DATA_BLOB data) +static WERROR regf_set_value(struct hive_key *key, const char *name, + uint32_t type, const DATA_BLOB data) { - const struct regf_key_data *private_data = + const struct regf_key_data *private_data = (const struct regf_key_data *)key; struct regf_data *regf = private_data->hive; struct nk_block *nk = private_data->nk; @@ -1600,9 +1694,11 @@ static WERROR regf_set_value(struct hive_key *key, const char *name, for (i = 0; i < nk->num_values; i++) { tmp_vk_offset = IVAL(values.data, i * 4); - if (!hbin_get_tdr(regf, tmp_vk_offset, private_data, - (tdr_pull_fn_t)tdr_pull_vk_block, &vk)) { - DEBUG(0, ("Unable to get VK block at %d\n", tmp_vk_offset)); + if (!hbin_get_tdr(regf, tmp_vk_offset, private_data, + (tdr_pull_fn_t)tdr_pull_vk_block, + &vk)) { + DEBUG(0, ("Unable to get VK block at %d\n", + tmp_vk_offset)); return WERR_GENERAL_FAILURE; } if (strcmp(vk.data_name, name) == 0) { @@ -1612,7 +1708,7 @@ static WERROR regf_set_value(struct hive_key *key, const char *name, } /* Free data, if any */ if (!(vk.data_length & 0x80000000)) { - hbin_free(regf, vk.data_offset); + hbin_free(regf, vk.data_offset); } } if (old_vk_offset == -1) { @@ -1638,15 +1734,21 @@ static WERROR regf_set_value(struct hive_key *key, const char *name, } if (old_vk_offset == -1) { /* Store new vk */ - vk_offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_vk_block, &vk); + vk_offset = hbin_store_tdr(regf, + (tdr_push_fn_t) tdr_push_vk_block, + &vk); } else { /* Store vk at offset */ - vk_offset = hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_vk_block, old_vk_offset ,&vk); + vk_offset = hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_vk_block, + old_vk_offset ,&vk); } /* Re-allocate the value list */ if (nk->values_offset == -1) { - nk->values_offset = hbin_store_tdr(regf, (tdr_push_fn_t) tdr_push_uint32, &vk_offset); + nk->values_offset = hbin_store_tdr(regf, + (tdr_push_fn_t) tdr_push_uint32, + &vk_offset); nk->num_values = 1; } else { @@ -1664,17 +1766,23 @@ static WERROR regf_set_value(struct hive_key *key, const char *name, DATA_BLOB value_list; value_list.length = (nk->num_values+1)*4; - value_list.data = (void *)talloc_array(private_data, uint32_t, nk->num_values+1); + value_list.data = (uint8_t *)talloc_array(private_data, + uint32_t, + nk->num_values+1); W_ERROR_HAVE_NO_MEMORY(value_list.data); memcpy(value_list.data, values.data, nk->num_values * 4); SIVAL(value_list.data, nk->num_values * 4, vk_offset); nk->num_values++; - nk->values_offset = hbin_store_resize(regf, nk->values_offset, value_list); + nk->values_offset = hbin_store_resize(regf, + nk->values_offset, + value_list); } - + } - hbin_store_tdr_resize(regf, (tdr_push_fn_t) tdr_push_nk_block, private_data->offset, nk); + hbin_store_tdr_resize(regf, + (tdr_push_fn_t) tdr_push_nk_block, + private_data->offset, nk); return regf_save_hbin(private_data->hive); } @@ -1698,8 +1806,9 @@ static WERROR regf_save_hbin(struct regf_data *regf) regf->header->chksum = regf_hdr_checksum(push->data.data); talloc_free(push); - if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, - (tdr_push_fn_t)tdr_push_regf_hdr, regf->header))) { + if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, + (tdr_push_fn_t)tdr_push_regf_hdr, + regf->header))) { DEBUG(0, ("Error writing registry file header\n")); return WERR_GENERAL_FAILURE; } @@ -1707,13 +1816,13 @@ static WERROR regf_save_hbin(struct regf_data *regf) if (lseek(regf->fd, 0x1000, SEEK_SET) == -1) { DEBUG(0, ("Error lseeking to 0x1000 in regf file\n")); return WERR_GENERAL_FAILURE; - } + } for (i = 0; regf->hbins[i]; i++) { - if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, - (tdr_push_fn_t)tdr_push_hbin_block, - regf->hbins[i]))) { - DEBUG(0, ("Error writing HBIN block\n")); + if (NT_STATUS_IS_ERR(tdr_push_to_fd(regf->fd, + (tdr_push_fn_t)tdr_push_hbin_block, + regf->hbins[i]))) { + DEBUG(0, ("Error writing HBIN block\n")); return WERR_GENERAL_FAILURE; } } @@ -1721,8 +1830,8 @@ static WERROR regf_save_hbin(struct regf_data *regf) return WERR_OK; } -WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, - int minor_version, struct hive_key **key) +WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, + int minor_version, struct hive_key **key) { struct regf_data *regf; struct regf_hdr *regf_hdr; @@ -1754,7 +1863,8 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, regf_hdr->version.major = 1; regf_hdr->version.minor = minor_version; regf_hdr->last_block = 0x1000; /* Block size */ - regf_hdr->description = talloc_strdup(regf_hdr, "registry created by Samba 4"); + regf_hdr->description = talloc_strdup(regf_hdr, + "registry created by Samba 4"); W_ERROR_HAVE_NO_MEMORY(regf_hdr->description); regf_hdr->chksum = 0; @@ -1785,14 +1895,16 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, nk.clsname_offset = -1; /* FIXME: fill in */ nk.clsname_length = 0; nk.key_name = ""; - + nk.sk_offset = -1; /* FIXME: fill in */ - + /* Store the new nk key */ - regf->header->data_offset = hbin_store_tdr(regf, - (tdr_push_fn_t)tdr_push_nk_block, &nk); - - *key = (struct hive_key *)regf_get_key(parent_ctx, regf, regf->header->data_offset); + regf->header->data_offset = hbin_store_tdr(regf, + (tdr_push_fn_t)tdr_push_nk_block, + &nk); + + *key = (struct hive_key *)regf_get_key(parent_ctx, regf, + regf->header->data_offset); /* We can drop our own reference now that *key will have created one */ talloc_free(regf); @@ -1805,8 +1917,8 @@ WERROR reg_create_regf_file(TALLOC_CTX *parent_ctx, const char *location, return WERR_OK; } -WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, - const char *location, struct hive_key **key) +WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, + const char *location, struct hive_key **key) { struct regf_data *regf; struct regf_hdr *regf_hdr; @@ -1850,7 +1962,7 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, if (strcmp(regf_hdr->REGF_ID, "regf") != 0) { DEBUG(0, ("Unrecognized NT registry header id: %s, %s\n", - regf_hdr->REGF_ID, location)); + regf_hdr->REGF_ID, location)); talloc_free(regf); return WERR_GENERAL_FAILURE; } @@ -1858,8 +1970,8 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, /* Validate the header ... */ if (regf_hdr_checksum(pull.data.data) != regf_hdr->chksum) { DEBUG(0, ("Registry file checksum error: %s: %d,%d\n", - location, regf_hdr->chksum, - regf_hdr_checksum(pull.data.data))); + location, regf_hdr->chksum, + regf_hdr_checksum(pull.data.data))); talloc_free(regf); return WERR_GENERAL_FAILURE; } @@ -1873,8 +1985,10 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, regf->hbins[0] = NULL; - while (pull.offset < pull.data.length && pull.offset <= regf->header->last_block) { - struct hbin_block *hbin = talloc(regf->hbins, struct hbin_block); + while (pull.offset < pull.data.length && + pull.offset <= regf->header->last_block) { + struct hbin_block *hbin = talloc(regf->hbins, + struct hbin_block); W_ERROR_HAVE_NO_MEMORY(hbin); @@ -1885,21 +1999,23 @@ WERROR reg_open_regf_file(TALLOC_CTX *parent_ctx, } if (strcmp(hbin->HBIN_ID, "hbin") != 0) { - DEBUG(0, ("[%d] Expected 'hbin', got '%s'\n", i, hbin->HBIN_ID)); + DEBUG(0, ("[%d] Expected 'hbin', got '%s'\n", + i, hbin->HBIN_ID)); talloc_free(regf); return WERR_FOOBAR; } regf->hbins[i] = hbin; i++; - regf->hbins = talloc_realloc(regf, regf->hbins, struct hbin_block *, i+2); + regf->hbins = talloc_realloc(regf, regf->hbins, + struct hbin_block *, i+2); regf->hbins[i] = NULL; - } + } DEBUG(1, ("%d HBIN blocks read\n", i)); - *key = (struct hive_key *)regf_get_key(parent_ctx, regf, - regf->header->data_offset); + *key = (struct hive_key *)regf_get_key(parent_ctx, regf, + regf->header->data_offset); /* We can drop our own reference now that *key will have created one */ talloc_free(regf); diff --git a/source4/lib/registry/registry.h b/source4/lib/registry/registry.h index 1d92a9edab..c1159dde2e 100644 --- a/source4/lib/registry/registry.h +++ b/source4/lib/registry/registry.h @@ -1,42 +1,43 @@ -/* +/* Unix SMB/CIFS implementation. Registry interface Copyright (C) Gerald Carter 2002. Copyright (C) Jelmer Vernooij 2003-2007. - + 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 3 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, see <http://www.gnu.org/licenses/>. */ #ifndef _REGISTRY_H /* _REGISTRY_H */ -#define _REGISTRY_H +#define _REGISTRY_H struct registry_context; #include <talloc.h> #include "librpc/gen_ndr/security.h" #include "lib/registry/hive.h" +#include "libcli/util/ntstatus.h" /* Handles for the predefined keys */ -#define HKEY_CLASSES_ROOT 0x80000000 -#define HKEY_CURRENT_USER 0x80000001 -#define HKEY_LOCAL_MACHINE 0x80000002 -#define HKEY_USERS 0x80000003 -#define HKEY_PERFORMANCE_DATA 0x80000004 -#define HKEY_CURRENT_CONFIG 0x80000005 -#define HKEY_DYN_DATA 0x80000006 -#define HKEY_PERFORMANCE_TEXT 0x80000050 -#define HKEY_PERFORMANCE_NLSTEXT 0x80000060 +#define HKEY_CLASSES_ROOT 0x80000000 +#define HKEY_CURRENT_USER 0x80000001 +#define HKEY_LOCAL_MACHINE 0x80000002 +#define HKEY_USERS 0x80000003 +#define HKEY_PERFORMANCE_DATA 0x80000004 +#define HKEY_CURRENT_CONFIG 0x80000005 +#define HKEY_DYN_DATA 0x80000006 +#define HKEY_PERFORMANCE_TEXT 0x80000050 +#define HKEY_PERFORMANCE_NLSTEXT 0x80000060 #define HKEY_FIRST HKEY_CLASSES_ROOT #define HKEY_LAST HKEY_PERFORMANCE_NLSTEXT @@ -60,18 +61,18 @@ extern const struct reg_predefined_key reg_predefined_keys[]; struct reg_key_operations; /* structure to store the registry handles */ -struct registry_key +struct registry_key { struct registry_context *context; }; #include "lib/registry/patchfile.h" -struct registry_value +struct registry_value { - const char *name; - unsigned int data_type; - DATA_BLOB data; + const char *name; + unsigned int data_type; + DATA_BLOB data; }; /* FIXME */ @@ -85,77 +86,77 @@ struct registry_operations { const char *name; WERROR (*get_key_info) (TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char **classname, - uint32_t *numsubkeys, - uint32_t *numvalues, - NTTIME *last_change_time); + const struct registry_key *key, + const char **classname, + uint32_t *numsubkeys, + uint32_t *numvalues, + NTTIME *last_change_time); WERROR (*flush_key) (struct registry_key *key); - WERROR (*get_predefined_key) (const struct registry_context *ctx, - uint32_t key_id, - struct registry_key **key); + WERROR (*get_predefined_key) (const struct registry_context *ctx, + uint32_t key_id, + struct registry_key **key); WERROR (*open_key) (TALLOC_CTX *mem_ctx, - struct registry_key *parent, - const char *path, - struct registry_key **key); + struct registry_key *parent, + const char *path, + struct registry_key **key); - WERROR (*create_key) (TALLOC_CTX *mem_ctx, - struct registry_key *parent, - const char *name, - const char *key_class, - struct security_descriptor *security, - struct registry_key **key); + WERROR (*create_key) (TALLOC_CTX *mem_ctx, + struct registry_key *parent, + const char *name, + const char *key_class, + struct security_descriptor *security, + struct registry_key **key); WERROR (*delete_key) (struct registry_key *key, const char *name); WERROR (*delete_value) (struct registry_key *key, const char *name); WERROR (*enum_key) (TALLOC_CTX *mem_ctx, - const struct registry_key *key, uint32_t idx, - const char **name, - const char **keyclass, - NTTIME *last_changed_time); + const struct registry_key *key, uint32_t idx, + const char **name, + const char **keyclass, + NTTIME *last_changed_time); WERROR (*enum_value) (TALLOC_CTX *mem_ctx, - const struct registry_key *key, uint32_t idx, - const char **name, - uint32_t *type, - DATA_BLOB *data); + const struct registry_key *key, uint32_t idx, + const char **name, + uint32_t *type, + DATA_BLOB *data); WERROR (*get_security) (TALLOC_CTX *mem_ctx, - const struct registry_key *key, - struct security_descriptor **security); + const struct registry_key *key, + struct security_descriptor **security); WERROR (*set_security) (struct registry_key *key, - const struct security_descriptor *security); + const struct security_descriptor *security); WERROR (*load_key) (struct registry_key *key, - const char *key_name, - const char *path); + const char *key_name, + const char *path); WERROR (*unload_key) (struct registry_key *key, const char *name); WERROR (*notify_value_change) (struct registry_key *key, - reg_value_notification_function fn); + reg_value_notification_function fn); WERROR (*get_value) (TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char *name, - uint32_t *type, - DATA_BLOB *data); + const struct registry_key *key, + const char *name, + uint32_t *type, + DATA_BLOB *data); WERROR (*set_value) (struct registry_key *key, - const char *name, - uint32_t type, - const DATA_BLOB data); -}; + const char *name, + uint32_t type, + const DATA_BLOB data); +}; /** * Handle to a full registry - * contains zero or more hives + * contains zero or more hives */ struct registry_context { const struct registry_operations *ops; @@ -167,113 +168,118 @@ struct event_context; /** * Open the locally defined registry. */ -WERROR reg_open_local (TALLOC_CTX *mem_ctx, - struct registry_context **ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials); +WERROR reg_open_local(TALLOC_CTX *mem_ctx, + struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials); -WERROR reg_open_samba (TALLOC_CTX *mem_ctx, - struct registry_context **ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials); +WERROR reg_open_samba(TALLOC_CTX *mem_ctx, + struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials); /** * Open the registry on a remote machine. */ -WERROR reg_open_remote(struct registry_context **ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - const char *location, struct event_context *ev); +WERROR reg_open_remote(struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + const char *location, struct event_context *ev); WERROR reg_open_wine(struct registry_context **ctx, const char *path); const char *reg_get_predef_name(uint32_t hkey); -WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, - const char *name, - struct registry_key **key); -WERROR reg_get_predefined_key(const struct registry_context *ctx, - uint32_t hkey, - struct registry_key **key); - -WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, - const char *name, struct registry_key **result); - -WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, - const struct registry_key *key, uint32_t idx, - const char **name, - uint32_t *type, - DATA_BLOB *data); +WERROR reg_get_predefined_key_by_name(struct registry_context *ctx, + const char *name, + struct registry_key **key); +WERROR reg_get_predefined_key(const struct registry_context *ctx, + uint32_t hkey, + struct registry_key **key); + +WERROR reg_open_key(TALLOC_CTX *mem_ctx, struct registry_key *parent, + const char *name, struct registry_key **result); + +WERROR reg_key_get_value_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *key, uint32_t idx, + const char **name, + uint32_t *type, + DATA_BLOB *data); WERROR reg_key_get_info(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char **class_name, - uint32_t *num_subkeys, - uint32_t *num_values, - NTTIME *last_change_time); -WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - int idx, - const char **name, - const char **classname, - NTTIME *last_mod_time); -WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char *name, - struct registry_key **subkey); -WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - const char *name, - uint32_t *type, - DATA_BLOB *data); + const struct registry_key *key, + const char **class_name, + uint32_t *num_subkeys, + uint32_t *num_values, + NTTIME *last_change_time); +WERROR reg_key_get_subkey_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + int idx, + const char **name, + const char **classname, + NTTIME *last_mod_time); +WERROR reg_key_get_subkey_by_name(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char *name, + struct registry_key **subkey); +WERROR reg_key_get_value_by_name(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + const char *name, + uint32_t *type, + DATA_BLOB *data); WERROR reg_key_del(struct registry_key *parent, const char *name); -WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, - struct registry_key *parent, const char *name, - const char *classname, - struct security_descriptor *desc, - struct registry_key **newkey); -WERROR reg_val_set(struct registry_key *key, const char *value, - uint32_t type, DATA_BLOB data); -WERROR reg_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, struct security_descriptor **secdesc); +WERROR reg_key_add_name(TALLOC_CTX *mem_ctx, + struct registry_key *parent, const char *name, + const char *classname, + struct security_descriptor *desc, + struct registry_key **newkey); +WERROR reg_val_set(struct registry_key *key, const char *value, + uint32_t type, DATA_BLOB data); +WERROR reg_get_sec_desc(TALLOC_CTX *ctx, const struct registry_key *key, + struct security_descriptor **secdesc); WERROR reg_del_value(struct registry_key *key, const char *valname); WERROR reg_key_flush(struct registry_key *key); -WERROR reg_create_key (TALLOC_CTX *mem_ctx, - struct registry_key *parent, - - const char *name, - const char *key_class, - struct security_descriptor *security, - struct registry_key **key); +WERROR reg_create_key(TALLOC_CTX *mem_ctx, + struct registry_key *parent, + const char *name, + const char *key_class, + struct security_descriptor *security, + struct registry_key **key); /* Utility functions */ const char *str_regtype(int type); -char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, - const DATA_BLOB data); +char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, + const DATA_BLOB data); char *reg_val_description(TALLOC_CTX *mem_ctx, const char *name, - uint32_t type, const DATA_BLOB data); -bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data); -WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result); + uint32_t type, const DATA_BLOB data); +bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, + const char *data_str, uint32_t *type, DATA_BLOB *data); +WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, + const char *name, struct registry_key **result); WERROR reg_key_del_abs(struct registry_context *ctx, const char *path); -WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx, const char *path, uint32_t access_mask, struct security_descriptor *sec_desc, struct registry_key **result); -WERROR reg_load_key(struct registry_context *ctx, struct registry_key *key, - const char *name, const char *filename); - -WERROR reg_mount_hive(struct registry_context *rctx, - struct hive_key *hive_key, - uint32_t key_id, - const char **elements); +WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx, + const char *path, uint32_t access_mask, + struct security_descriptor *sec_desc, + struct registry_key **result); +WERROR reg_load_key(struct registry_context *ctx, struct registry_key *key, + const char *name, const char *filename); + +WERROR reg_mount_hive(struct registry_context *rctx, + struct hive_key *hive_key, + uint32_t key_id, + const char **elements); struct registry_key *reg_import_hive_key(struct registry_context *ctx, - struct hive_key *hive, - uint32_t predef_key, - const char **elements); -WERROR reg_get_security(TALLOC_CTX *mem_ctx, - const struct registry_key *key, - struct security_descriptor **security); - -WERROR reg_set_security(struct registry_key *key, - struct security_descriptor *security); + struct hive_key *hive, + uint32_t predef_key, + const char **elements); +WERROR reg_get_security(TALLOC_CTX *mem_ctx, + const struct registry_key *key, + struct security_descriptor **security); + +WERROR reg_set_security(struct registry_key *key, + struct security_descriptor *security); #endif /* _REGISTRY_H */ diff --git a/source4/lib/registry/rpc.c b/source4/lib/registry/rpc.c index e4157fe424..c694223909 100644 --- a/source4/lib/registry/rpc.c +++ b/source4/lib/registry/rpc.c @@ -7,15 +7,15 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>. */ - + #include "includes.h" #include "registry.h" #include "librpc/gen_ndr/ndr_winreg_c.h" @@ -76,7 +76,8 @@ openhive(HKCC) static struct { uint32_t hkey; - WERROR (*open) (struct dcerpc_pipe *p, TALLOC_CTX *, struct policy_handle *h); + WERROR (*open) (struct dcerpc_pipe *p, TALLOC_CTX *, + struct policy_handle *h); } known_hives[] = { { HKEY_LOCAL_MACHINE, open_HKLM }, { HKEY_CURRENT_USER, open_HKCU }, @@ -90,20 +91,20 @@ static struct { static WERROR rpc_query_key(const struct registry_key *k); -static WERROR rpc_get_predefined_key(const struct registry_context *ctx, - uint32_t hkey_type, - struct registry_key **k) +static WERROR rpc_get_predefined_key(const struct registry_context *ctx, + uint32_t hkey_type, + struct registry_key **k) { int n; - struct rpc_registry_context *rctx = talloc_get_type(ctx, - struct rpc_registry_context); + struct rpc_registry_context *rctx = talloc_get_type(ctx, + struct rpc_registry_context); struct rpc_key *mykeydata; for(n = 0; known_hives[n].hkey; n++) { - if(known_hives[n].hkey == hkey_type) + if(known_hives[n].hkey == hkey_type) break; } - + if (known_hives[n].open == NULL) { DEBUG(1, ("No such hive %d\n", hkey_type)); return WERR_NO_MORE_ITEMS; @@ -119,7 +120,7 @@ static WERROR rpc_get_predefined_key(const struct registry_context *ctx, #if 0 static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) { - struct winreg_OpenKey r; + struct winreg_OpenKey r; struct rpc_key_data *mykeydata; k->backend_data = mykeydata = talloc(mem_ctx, struct rpc_key_data); @@ -129,46 +130,47 @@ static WERROR rpc_key_put_rpc_data(TALLOC_CTX *mem_ctx, struct registry_key *k) /* Then, open the handle using the hive */ memset(&r, 0, sizeof(struct winreg_OpenKey)); - r.in.handle = &(((struct rpc_key_data *)k->hive->root->backend_data)->pol); - init_winreg_String(&r.in.keyname, k->path); - r.in.unknown = 0x00000000; - r.in.access_mask = 0x02000000; - r.out.handle = &mykeydata->pol; + r.in.handle = &(((struct rpc_key_data *)k->hive->root->backend_data)->pol); + init_winreg_String(&r.in.keyname, k->path); + r.in.unknown = 0x00000000; + r.in.access_mask = 0x02000000; + r.out.handle = &mykeydata->pol; - dcerpc_winreg_OpenKey((struct dcerpc_pipe *)k->hive->backend_data, mem_ctx, &r); + dcerpc_winreg_OpenKey((struct dcerpc_pipe *)k->hive->backend_data, + mem_ctx, &r); return r.out.result; } #endif -static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, - const char *name, struct registry_key **key) +static WERROR rpc_open_key(TALLOC_CTX *mem_ctx, struct registry_key *h, + const char *name, struct registry_key **key) { struct rpc_key *mykeydata = talloc_get_type(h, struct rpc_key), - *newkeydata; - struct winreg_OpenKey r; + *newkeydata; + struct winreg_OpenKey r; mykeydata = talloc(mem_ctx, struct rpc_key); /* Then, open the handle using the hive */ memset(&r, 0, sizeof(struct winreg_OpenKey)); - r.in.parent_handle = &mykeydata->pol; - init_winreg_String(&r.in.keyname, name); - r.in.unknown = 0x00000000; - r.in.access_mask = 0x02000000; - r.out.handle = &newkeydata->pol; + r.in.parent_handle = &mykeydata->pol; + init_winreg_String(&r.in.keyname, name); + r.in.unknown = 0x00000000; + r.in.access_mask = 0x02000000; + r.out.handle = &newkeydata->pol; - dcerpc_winreg_OpenKey(mykeydata->pipe, mem_ctx, &r); + dcerpc_winreg_OpenKey(mykeydata->pipe, mem_ctx, &r); return r.out.result; } -static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, - const struct registry_key *parent, - uint32_t n, - const char **value_name, - uint32_t *type, - DATA_BLOB *data) +static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *parent, + uint32_t n, + const char **value_name, + uint32_t *type, + DATA_BLOB *data) { struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key); WERROR error; @@ -177,14 +179,14 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, NTSTATUS status; struct winreg_StringBuf name; uint8_t u8; - + if (mykeydata->num_values == -1) { error = rpc_query_key(parent); if(!W_ERROR_IS_OK(error)) return error; } len1 = mykeydata->max_valdatalen; - + name.length = 0; name.size = mykeydata->max_valnamelen * 2; name.name = ""; @@ -197,29 +199,29 @@ static WERROR rpc_get_value_by_index(TALLOC_CTX *mem_ctx, r.in.length = &zero; r.in.size = &len1; r.out.name = &name; - + status = dcerpc_winreg_EnumValue(mykeydata->pipe, mem_ctx, &r); if(NT_STATUS_IS_ERR(status)) { DEBUG(0, ("Error in EnumValue: %s\n", nt_errstr(status))); return WERR_GENERAL_FAILURE; } - - if(NT_STATUS_IS_OK(status) && + + if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result) && r.out.length) { *value_name = talloc_strdup(mem_ctx, r.out.name->name); *data = data_blob_talloc(mem_ctx, r.out.value, *r.out.length); return WERR_OK; } - + return r.out.result; } -static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, - const struct registry_key *parent, - uint32_t n, - const char **name, - const char **keyclass, - NTTIME *last_changed_time) +static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, + const struct registry_key *parent, + uint32_t n, + const char **name, + const char **keyclass, + NTTIME *last_changed_time) { struct winreg_EnumKey r; struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key); @@ -242,7 +244,7 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, r.out.name = &namebuf; status = dcerpc_winreg_EnumKey(mykeydata->pipe, mem_ctx, &r); - if(NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { + if (NT_STATUS_IS_OK(status) && W_ERROR_IS_OK(r.out.result)) { *name = talloc_strdup(mem_ctx, r.out.name->name); *keyclass = talloc_strdup(mem_ctx, r.out.keyclass->name); *last_changed_time = *r.out.last_changed_time; @@ -251,11 +253,11 @@ static WERROR rpc_get_subkey_by_index(TALLOC_CTX *mem_ctx, return r.out.result; } -static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, - struct registry_key *parent, const char *name, - const char *key_class, - struct security_descriptor *sec, - struct registry_key **key) +static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, + struct registry_key *parent, const char *name, + const char *key_class, + struct security_descriptor *sec, + struct registry_key **key) { NTSTATUS status; struct winreg_CreateKey r; @@ -273,11 +275,11 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, status = dcerpc_winreg_CreateKey(parentkd->pipe, mem_ctx, &r); - if (!NT_STATUS_IS_OK(status)) { + if (!NT_STATUS_IS_OK(status)) { talloc_free(rpck); - DEBUG(1, ("CreateKey failed - %s\n", nt_errstr(status))); - return ntstatus_to_werror(status); - } + DEBUG(1, ("CreateKey failed - %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); + } if (W_ERROR_IS_OK(r.out.result)) { rpck->pipe = talloc_reference(rpck, parentkd->pipe); @@ -289,29 +291,29 @@ static WERROR rpc_add_key(TALLOC_CTX *mem_ctx, static WERROR rpc_query_key(const struct registry_key *k) { - NTSTATUS status; - struct winreg_QueryInfoKey r; - struct rpc_key *mykeydata = talloc_get_type(k, struct rpc_key); + NTSTATUS status; + struct winreg_QueryInfoKey r; + struct rpc_key *mykeydata = talloc_get_type(k, struct rpc_key); TALLOC_CTX *mem_ctx = talloc_init("query_key"); r.in.classname = talloc(mem_ctx, struct winreg_String); - init_winreg_String(r.in.classname, NULL); - r.in.handle = &mykeydata->pol; - - status = dcerpc_winreg_QueryInfoKey(mykeydata->pipe, mem_ctx, &r); + init_winreg_String(r.in.classname, NULL); + r.in.handle = &mykeydata->pol; + + status = dcerpc_winreg_QueryInfoKey(mykeydata->pipe, mem_ctx, &r); talloc_free(mem_ctx); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(1, ("QueryInfoKey failed - %s\n", nt_errstr(status))); - return ntstatus_to_werror(status); - } - - if (W_ERROR_IS_OK(r.out.result)) { + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("QueryInfoKey failed - %s\n", nt_errstr(status))); + return ntstatus_to_werror(status); + } + + if (W_ERROR_IS_OK(r.out.result)) { mykeydata->num_subkeys = *r.out.num_subkeys; mykeydata->num_values = *r.out.num_values; mykeydata->max_valnamelen = *r.out.max_valnamelen; mykeydata->max_valdatalen = *r.out.max_valbufsize; - } + } return r.out.result; } @@ -322,11 +324,11 @@ static WERROR rpc_del_key(struct registry_key *parent, const char *name) struct rpc_key *mykeydata = talloc_get_type(parent, struct rpc_key); struct winreg_DeleteKey r; TALLOC_CTX *mem_ctx = talloc_init("del_key"); - - r.in.handle = &mykeydata->pol; - init_winreg_String(&r.in.key, name); - - status = dcerpc_winreg_DeleteKey(mykeydata->pipe, mem_ctx, &r); + + r.in.handle = &mykeydata->pol; + init_winreg_String(&r.in.key, name); + + status = dcerpc_winreg_DeleteKey(mykeydata->pipe, mem_ctx, &r); talloc_free(mem_ctx); @@ -334,19 +336,19 @@ static WERROR rpc_del_key(struct registry_key *parent, const char *name) } static WERROR rpc_get_info(TALLOC_CTX *mem_ctx, const struct registry_key *key, - const char **classname, + const char **classname, uint32_t *numsubkeys, uint32_t *numvalue, NTTIME *last_changed_time) { struct rpc_key *mykeydata = talloc_get_type(key, struct rpc_key); WERROR error; - - if(mykeydata->num_values == -1) { + + if (mykeydata->num_values == -1) { error = rpc_query_key(key); if(!W_ERROR_IS_OK(error)) return error; } - + /* FIXME: *classname = talloc_strdup(mem_ctx, mykeydata->classname); */ /* FIXME: *last_changed_time = mykeydata->last_changed_time */ @@ -370,10 +372,10 @@ static struct registry_operations reg_backend_rpc = { .get_predefined_key = rpc_get_predefined_key, }; -_PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials, - const char *location, struct event_context *ev) +_PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials, + const char *location, struct event_context *ev) { NTSTATUS status; struct dcerpc_pipe *p; @@ -388,14 +390,15 @@ _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, location = talloc_strdup(ctx, "ncalrpc:"); } - status = dcerpc_pipe_connect(*ctx /* TALLOC_CTX */, - &p, location, + status = dcerpc_pipe_connect(*ctx /* TALLOC_CTX */, + &p, location, &ndr_table_winreg, credentials, ev); rctx->pipe = p; if(NT_STATUS_IS_ERR(status)) { - DEBUG(1, ("Unable to open '%s': %s\n", location, nt_errstr(status))); + DEBUG(1, ("Unable to open '%s': %s\n", location, + nt_errstr(status))); talloc_free(*ctx); *ctx = NULL; return ntstatus_to_werror(status); diff --git a/source4/lib/registry/samba.c b/source4/lib/registry/samba.c index 6aaaa118d0..2397432f0b 100644 --- a/source4/lib/registry/samba.c +++ b/source4/lib/registry/samba.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. Copyright (C) Jelmer Vernooij 2004-2007. @@ -18,29 +18,32 @@ #include "includes.h" #include "registry.h" +#include "param/param.h" /** * @file * @brief Samba-specific registry functions */ -WERROR mount_samba_hive(struct registry_context *ctx, - struct auth_session_info *auth_info, - struct cli_credentials *creds, - const char *name, - uint32_t hive_id) +static WERROR mount_samba_hive(struct registry_context *ctx, + struct auth_session_info *auth_info, + struct cli_credentials *creds, + const char *name, + uint32_t hive_id) { WERROR error; struct hive_key *hive; const char *location; - location = talloc_asprintf(ctx, "%s/%s.ldb", lp_private_dir(), name); - + location = talloc_asprintf(ctx, "%s/%s.ldb", + lp_private_dir(global_loadparm), + name); error = reg_open_hive(ctx, location, auth_info, creds, &hive); if (W_ERROR_EQUAL(error, WERR_NOT_FOUND)) - error = reg_open_ldb_file(ctx, location, auth_info, creds, &hive); + error = reg_open_ldb_file(ctx, location, auth_info, + creds, &hive); if (!W_ERROR_IS_OK(error)) return error; @@ -49,10 +52,10 @@ WERROR mount_samba_hive(struct registry_context *ctx, } -_PUBLIC_ WERROR reg_open_samba (TALLOC_CTX *mem_ctx, - struct registry_context **ctx, - struct auth_session_info *session_info, - struct cli_credentials *credentials) +_PUBLIC_ WERROR reg_open_samba(TALLOC_CTX *mem_ctx, + struct registry_context **ctx, + struct auth_session_info *session_info, + struct cli_credentials *credentials) { WERROR result; @@ -61,19 +64,19 @@ _PUBLIC_ WERROR reg_open_samba (TALLOC_CTX *mem_ctx, return result; } - mount_samba_hive(*ctx, session_info, credentials, - "hklm", HKEY_LOCAL_MACHINE); + mount_samba_hive(*ctx, session_info, credentials, + "hklm", HKEY_LOCAL_MACHINE); - mount_samba_hive(*ctx, session_info, credentials, - "hkcr", HKEY_CLASSES_ROOT); + mount_samba_hive(*ctx, session_info, credentials, + "hkcr", HKEY_CLASSES_ROOT); - /* FIXME: Should be mounted from NTUSER.DAT in the home directory of the + /* FIXME: Should be mounted from NTUSER.DAT in the home directory of the * current user */ - mount_samba_hive(*ctx, session_info, credentials, - "hkcu", HKEY_CURRENT_USER); + mount_samba_hive(*ctx, session_info, credentials, + "hkcu", HKEY_CURRENT_USER); - mount_samba_hive(*ctx, session_info, credentials, - "hku", HKEY_USERS); + mount_samba_hive(*ctx, session_info, credentials, + "hku", HKEY_USERS); /* FIXME: Different hive backend for HKEY_CLASSES_ROOT: merged view of HKEY_LOCAL_MACHINE\Software\Classes * and HKEY_CURRENT_USER\Software\Classes */ @@ -85,6 +88,6 @@ _PUBLIC_ WERROR reg_open_samba (TALLOC_CTX *mem_ctx, /* FIXME: HKEY_LOCAL_MACHINE\Hardware is autogenerated */ /* FIXME: HKEY_LOCAL_MACHINE\Security\SAM is an alias for HKEY_LOCAL_MACHINE\SAM */ - + return WERR_OK; } diff --git a/source4/lib/registry/tests/hive.c b/source4/lib/registry/tests/hive.c index a04bc1168e..dff6d1e829 100644 --- a/source4/lib/registry/tests/hive.c +++ b/source4/lib/registry/tests/hive.c @@ -27,13 +27,10 @@ #include "librpc/gen_ndr/winreg.h" #include "system/filesys.h" -NTSTATUS torture_temp_dir(struct torture_context *tctx, const char *prefix, - const char **tempdir); - static bool test_del_nonexistant_key(struct torture_context *tctx, - const void *test_data) + const void *test_data) { - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; WERROR error = hive_key_del(root, "bla"); torture_assert_werr_equal(tctx, error, WERR_NOT_FOUND, "invalid return code"); @@ -45,7 +42,7 @@ static bool test_keyinfo_root(struct torture_context *tctx, const void *test_data) { uint32_t num_subkeys, num_values; - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; WERROR error; /* This is a new backend. There should be no subkeys and no @@ -67,7 +64,7 @@ static bool test_keyinfo_nums(struct torture_context *tctx, const void *test_data) { uint32_t num_subkeys, num_values; - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; WERROR error; struct hive_key *subkey; uint32_t data = 42; @@ -100,7 +97,7 @@ static bool test_add_subkey(struct torture_context *tctx, { WERROR error; struct hive_key *subkey; - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; error = hive_key_add_name(mem_ctx, root, "Nested Key", NULL, @@ -114,9 +111,9 @@ static bool test_add_subkey(struct torture_context *tctx, } static bool test_flush_key(struct torture_context *tctx, - const void *test_data) + const void *test_data) { - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; torture_assert_werr_ok(tctx, hive_key_flush(root), "flush key"); @@ -127,7 +124,7 @@ static bool test_del_key(struct torture_context *tctx, const void *test_data) { WERROR error; struct hive_key *subkey; - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; error = hive_key_add_name(mem_ctx, root, "Nested Key", NULL, @@ -148,7 +145,7 @@ static bool test_set_value(struct torture_context *tctx, { WERROR error; struct hive_key *subkey; - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; uint32_t data = 42; @@ -167,7 +164,7 @@ static bool test_get_value(struct torture_context *tctx, const void *test_data) { WERROR error; struct hive_key *subkey; - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; uint32_t data = 42; uint32_t type; @@ -200,7 +197,7 @@ static bool test_del_value(struct torture_context *tctx, const void *test_data) { WERROR error; struct hive_key *subkey; - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; uint32_t data = 42; uint32_t type; @@ -231,7 +228,7 @@ static bool test_list_values(struct torture_context *tctx, { WERROR error; struct hive_key *subkey; - const struct hive_key *root = test_data; + const struct hive_key *root = (const struct hive_key *)test_data; TALLOC_CTX *mem_ctx = tctx; uint32_t data = 42; uint32_t type; diff --git a/source4/lib/registry/tests/registry.c b/source4/lib/registry/tests/registry.c index fd2e98eac8..962c7fd2b5 100644 --- a/source4/lib/registry/tests/registry.c +++ b/source4/lib/registry/tests/registry.c @@ -28,16 +28,14 @@ #include "libcli/security/security.h" #include "system/filesys.h" -NTSTATUS torture_temp_dir(struct torture_context *tctx, const char *prefix, - const char **tempdir); - /** * Test obtaining a predefined key. */ static bool test_get_predefined(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root; WERROR error; @@ -66,7 +64,8 @@ static bool test_get_predefined_unknown(struct torture_context *tctx, static bool test_predef_key_by_name(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root; WERROR error; @@ -84,7 +83,8 @@ static bool test_predef_key_by_name(struct torture_context *tctx, static bool test_predef_key_by_name_invalid(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root; WERROR error; @@ -100,7 +100,8 @@ static bool test_predef_key_by_name_invalid(struct torture_context *tctx, static bool test_create_subkey(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root, *newkey; WERROR error; @@ -121,7 +122,8 @@ static bool test_create_subkey(struct torture_context *tctx, static bool test_create_nested_subkey(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root, *newkey1, *newkey2; WERROR error; @@ -132,7 +134,7 @@ static bool test_create_nested_subkey(struct torture_context *tctx, error = reg_key_add_name(rctx, root, "Hamburg", NULL, NULL, &newkey1); torture_assert_werr_ok(tctx, error, "Creating key return code"); - torture_assert(tctx, newkey2 != NULL, "Creating new key"); + torture_assert(tctx, newkey1 != NULL, "Creating new key"); error = reg_key_add_name(rctx, root, "Hamburg\\Hamburg", NULL, NULL, &newkey2); @@ -148,7 +150,8 @@ static bool test_create_nested_subkey(struct torture_context *tctx, static bool test_key_add_abs_top(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root; WERROR error; @@ -165,7 +168,8 @@ static bool test_key_add_abs(struct torture_context *tctx, const void *_data) { WERROR error; - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root, *result1, *result2; error = reg_key_add_abs(tctx, rctx, "HKEY_CLASSES_ROOT\\bloe", 0, NULL, &result1); @@ -190,7 +194,8 @@ static bool test_key_add_abs(struct torture_context *tctx, static bool test_del_key(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root, *newkey; WERROR error; @@ -238,7 +243,8 @@ static bool create_test_key(struct torture_context *tctx, static bool test_flush_key(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root, *subkey; WERROR error; @@ -256,7 +262,8 @@ static bool test_flush_key(struct torture_context *tctx, const void *_data) static bool test_query_key(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root, *subkey; WERROR error; NTTIME last_changed_time; @@ -280,7 +287,8 @@ static bool test_query_key(struct torture_context *tctx, const void *_data) static bool test_query_key_nums(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *root, *subkey1, *subkey2; WERROR error; uint32_t num_subkeys, num_values; @@ -313,7 +321,8 @@ static bool test_query_key_nums(struct torture_context *tctx, const void *_data) */ static bool test_list_subkeys(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; NTTIME last_mod_time; @@ -351,7 +360,8 @@ static bool test_list_subkeys(struct torture_context *tctx, const void *_data) */ static bool test_set_value(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; uint32_t data = 42; @@ -371,10 +381,10 @@ static bool test_set_value(struct torture_context *tctx, const void *_data) */ static bool test_security(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; - uint32_t data = 42; struct security_descriptor *osd, *nsd; if (!create_test_key(tctx, rctx, "Düsseldorf", &root, &subkey)) @@ -405,7 +415,8 @@ static bool test_security(struct torture_context *tctx, const void *_data) */ static bool test_get_value(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; DATA_BLOB data; @@ -440,7 +451,8 @@ static bool test_get_value(struct torture_context *tctx, const void *_data) */ static bool test_del_value(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; DATA_BLOB data; @@ -474,7 +486,8 @@ static bool test_del_value(struct torture_context *tctx, const void *_data) */ static bool test_list_values(struct torture_context *tctx, const void *_data) { - const struct registry_context *rctx = _data; + const struct registry_context *rctx = + (const struct registry_context *)_data; struct registry_key *subkey = NULL, *root; WERROR error; DATA_BLOB data; @@ -511,26 +524,20 @@ static bool setup_local_registry(struct torture_context *tctx, void **data) const char *tempdir; NTSTATUS status; struct hive_key *hive_key; + const char *filename; error = reg_open_local(tctx, &rctx, NULL, NULL); - if (!W_ERROR_IS_OK(error)) - return false; + torture_assert_werr_ok(tctx, error, "Opening local registry failed"); status = torture_temp_dir(tctx, "registry-local", &tempdir); - if (!NT_STATUS_IS_OK(status)) - return false; + torture_assert_ntstatus_ok(tctx, status, "Creating temp dir failed"); - error = reg_open_ldb_file(tctx, - talloc_asprintf(tctx, "%s/classes_root.ldb", tempdir), - NULL, - NULL, - &hive_key); - if (!W_ERROR_IS_OK(error)) - return false; + filename = talloc_asprintf(tctx, "%s/classes_root.ldb", tempdir); + error = reg_open_ldb_file(tctx, filename, NULL, NULL, &hive_key); + torture_assert_werr_ok(tctx, error, "Opening classes_root file failed"); error = reg_mount_hive(rctx, hive_key, HKEY_CLASSES_ROOT, NULL); - if (!W_ERROR_IS_OK(error)) - return false; + torture_assert_werr_ok(tctx, error, "Mounting hive failed"); *data = rctx; @@ -540,13 +547,10 @@ static bool setup_local_registry(struct torture_context *tctx, void **data) static void tcase_add_tests(struct torture_tcase *tcase) { torture_tcase_add_simple_test(tcase, "list_subkeys", test_list_subkeys); - torture_tcase_add_simple_test(tcase, "get_predefined_key", - test_get_predefined); - torture_tcase_add_simple_test(tcase, "get_predefined_key", - test_get_predefined_unknown); + torture_tcase_add_simple_test(tcase, "get_predefined_key", test_get_predefined); + torture_tcase_add_simple_test(tcase, "get_predefined_key", test_get_predefined_unknown); torture_tcase_add_simple_test(tcase, "create_key", test_create_subkey); - torture_tcase_add_simple_test(tcase, "create_key", - test_create_nested_subkey); + torture_tcase_add_simple_test(tcase, "create_key", test_create_nested_subkey); torture_tcase_add_simple_test(tcase, "key_add_abs", test_key_add_abs); torture_tcase_add_simple_test(tcase, "key_add_abs_top", test_key_add_abs_top); torture_tcase_add_simple_test(tcase, "set_value", test_set_value); @@ -558,18 +562,16 @@ static void tcase_add_tests(struct torture_tcase *tcase) torture_tcase_add_simple_test(tcase, "query_key", test_query_key); torture_tcase_add_simple_test(tcase, "query_key_nums", test_query_key_nums); torture_tcase_add_simple_test(tcase, "test_predef_key_by_name", - test_predef_key_by_name); - torture_tcase_add_simple_test(tcase, "security", - test_security); + test_predef_key_by_name); + torture_tcase_add_simple_test(tcase, "security", test_security); torture_tcase_add_simple_test(tcase, "test_predef_key_by_name_invalid", - test_predef_key_by_name_invalid); + test_predef_key_by_name_invalid); } struct torture_suite *torture_registry_registry(TALLOC_CTX *mem_ctx) { struct torture_tcase *tcase; - struct torture_suite *suite = torture_suite_create(mem_ctx, - "REGISTRY"); + struct torture_suite *suite = torture_suite_create(mem_ctx, "REGISTRY"); tcase = torture_suite_add_tcase(suite, "local"); torture_tcase_set_fixture(tcase, setup_local_registry, NULL); diff --git a/source4/lib/registry/tools/common.c b/source4/lib/registry/tools/common.c index c8b0945c2c..aa11eccbee 100644 --- a/source4/lib/registry/tools/common.c +++ b/source4/lib/registry/tools/common.c @@ -21,6 +21,7 @@ #include "includes.h" #include "auth/credentials/credentials.h" #include "lib/registry/registry.h" +#include "lib/registry/tools/common.h" struct registry_context *reg_common_open_remote(const char *remote, struct cli_credentials *creds) { diff --git a/source4/lib/registry/tools/regshell.c b/source4/lib/registry/tools/regshell.c index 131d76fff5..cdf688b39e 100644 --- a/source4/lib/registry/tools/regshell.c +++ b/source4/lib/registry/tools/regshell.c @@ -262,8 +262,7 @@ static WERROR cmd_rmval(struct regshell_context *ctx, int argc, char **argv) return WERR_OK; } -static WERROR cmd_exit(struct regshell_context *ctx, - int argc, char **argv) +_NORETURN_ static WERROR cmd_exit(struct regshell_context *ctx, int argc, char **argv) { exit(0); return WERR_OK; @@ -275,8 +274,7 @@ static struct { const char *name; const char *alias; const char *help; - WERROR (*handle)(struct regshell_context *ctx, - int argc, char **argv); + WERROR (*handle)(struct regshell_context *ctx, int argc, char **argv); } regshell_cmds[] = { {"ck", "cd", "Change current key", cmd_ck }, {"info", "i", "Show detailed information of a key", cmd_info }, diff --git a/source4/lib/registry/util.c b/source4/lib/registry/util.c index 6afd1bc44c..ca3e3dd619 100644 --- a/source4/lib/registry/util.c +++ b/source4/lib/registry/util.c @@ -1,4 +1,4 @@ -/* +/* Unix SMB/CIFS implementation. Transparent registry backend handling Copyright (C) Jelmer Vernooij 2003-2007. @@ -43,60 +43,59 @@ _PUBLIC_ const char *str_regtype(int type) { int i; for (i = 0; reg_value_types[i].name; i++) { - if (reg_value_types[i].id == type) + if (reg_value_types[i].id == type) return reg_value_types[i].name; } return "Unknown"; } -_PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, - const DATA_BLOB data) -{ - char *ret = NULL; - - if (data.length == 0) - return talloc_strdup(mem_ctx, ""); - - switch (type) { - case REG_EXPAND_SZ: - case REG_SZ: - convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, data.data, data.length, - (void **)&ret); - return ret; - - case REG_BINARY: - ret = data_blob_hex_string(mem_ctx, &data); - return ret; - - case REG_DWORD: - if (*(int *)data.data == 0) - return talloc_strdup(mem_ctx, "0"); - - return talloc_asprintf(mem_ctx, "0x%x", *(int *)data.data); +_PUBLIC_ char *reg_val_data_string(TALLOC_CTX *mem_ctx, uint32_t type, + const DATA_BLOB data) +{ + char *ret = NULL; - case REG_MULTI_SZ: - /* FIXME */ - break; + if (data.length == 0) + return talloc_strdup(mem_ctx, ""); - default: - break; - } + switch (type) { + case REG_EXPAND_SZ: + case REG_SZ: + convert_string_talloc(mem_ctx, CH_UTF16, CH_UNIX, + data.data, data.length, + (void **)&ret); + return ret; + case REG_BINARY: + ret = data_blob_hex_string(mem_ctx, &data); + return ret; + case REG_DWORD: + if (*(int *)data.data == 0) + return talloc_strdup(mem_ctx, "0"); + return talloc_asprintf(mem_ctx, "0x%x", + *(int *)data.data); + case REG_MULTI_SZ: + /* FIXME */ + break; + default: + break; + } - return ret; + return ret; } /** Generate a string that describes a registry value */ -_PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx, const char *name, - uint32_t data_type, - const DATA_BLOB data) +_PUBLIC_ char *reg_val_description(TALLOC_CTX *mem_ctx, const char *name, + uint32_t data_type, + const DATA_BLOB data) { - return talloc_asprintf(mem_ctx, "%s = %s : %s", name?name:"<No Name>", - str_regtype(data_type), - reg_val_data_string(mem_ctx, data_type, data)); + return talloc_asprintf(mem_ctx, "%s = %s : %s", name?name:"<No Name>", + str_regtype(data_type), + reg_val_data_string(mem_ctx, data_type, data)); } -_PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const char *data_str, uint32_t *type, DATA_BLOB *data) +_PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, + const char *data_str, uint32_t *type, + DATA_BLOB *data) { int i; *type = -1; @@ -109,16 +108,18 @@ _PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const } } - if (*type == -1) + if (*type == -1) return false; /* Convert data appropriately */ - switch (*type) + switch (*type) { case REG_SZ: case REG_EXPAND_SZ: - data->length = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, data_str, strlen(data_str), (void **)&data->data); + data->length = convert_string_talloc(mem_ctx, CH_UNIX, CH_UTF16, + data_str, strlen(data_str), + (void **)&data->data); break; case REG_DWORD: { @@ -130,12 +131,12 @@ _PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const case REG_NONE: ZERO_STRUCTP(data); break; - - case REG_BINARY: + + case REG_BINARY: *data = strhex_to_data_blob(data_str); talloc_steal(mem_ctx, data->data); break; - + default: /* FIXME */ return false; @@ -144,16 +145,17 @@ _PUBLIC_ bool reg_string_to_val(TALLOC_CTX *mem_ctx, const char *type_str, const } /** Open a key by name (including the predefined key name!) */ -WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, const char *name, struct registry_key **result) +WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, + const char *name, struct registry_key **result) { struct registry_key *predef; WERROR error; int predeflength; char *predefname; - if (strchr(name, '\\') != NULL) + if (strchr(name, '\\') != NULL) predeflength = strchr(name, '\\')-name; - else + else predeflength = strlen(name); predefname = talloc_strndup(mem_ctx, name, predeflength); @@ -165,31 +167,32 @@ WERROR reg_open_key_abs(TALLOC_CTX *mem_ctx, struct registry_context *handle, co } if (strchr(name, '\\')) { - return reg_open_key(mem_ctx, predef, strchr(name, '\\')+1, result); + return reg_open_key(mem_ctx, predef, strchr(name, '\\')+1, + result); } else { *result = predef; return WERR_OK; } } -static WERROR get_abs_parent(TALLOC_CTX *mem_ctx, struct registry_context *ctx, - const char *path, struct registry_key **parent, - const char **name) +static WERROR get_abs_parent(TALLOC_CTX *mem_ctx, struct registry_context *ctx, + const char *path, struct registry_key **parent, + const char **name) { char *parent_name; WERROR error; - + if (strchr(path, '\\') == NULL) { return WERR_FOOBAR; } - + parent_name = talloc_strndup(mem_ctx, path, strrchr(path, '\\')-path); error = reg_open_key_abs(mem_ctx, ctx, parent_name, parent); if (!W_ERROR_IS_OK(error)) { return error; } - + *name = talloc_strdup(mem_ctx, strrchr(path, '\\')+1); return WERR_OK; @@ -201,11 +204,11 @@ WERROR reg_key_del_abs(struct registry_context *ctx, const char *path) const char *n; TALLOC_CTX *mem_ctx = talloc_init("reg_key_del_abs"); WERROR error; - + if (!strchr(path, '\\')) { return WERR_FOOBAR; } - + error = get_abs_parent(mem_ctx, ctx, path, &parent, &n); if (W_ERROR_IS_OK(error)) { error = reg_key_del(parent, n); @@ -216,22 +219,22 @@ WERROR reg_key_del_abs(struct registry_context *ctx, const char *path) return error; } -WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx, - const char *path, uint32_t access_mask, - struct security_descriptor *sec_desc, - struct registry_key **result) +WERROR reg_key_add_abs(TALLOC_CTX *mem_ctx, struct registry_context *ctx, + const char *path, uint32_t access_mask, + struct security_descriptor *sec_desc, + struct registry_key **result) { struct registry_key *parent; const char *n; WERROR error; - + if (!strchr(path, '\\')) { return WERR_ALREADY_EXISTS; } - + error = get_abs_parent(mem_ctx, ctx, path, &parent, &n); if (!W_ERROR_IS_OK(error)) { - DEBUG(2, ("Opening parent of %s failed with %s\n", path, + DEBUG(2, ("Opening parent of %s failed with %s\n", path, win_errstr(error))); return error; } diff --git a/source4/lib/registry/wine.c b/source4/lib/registry/wine.c index 2cb0b9955e..77d2ce66e9 100644 --- a/source4/lib/registry/wine.c +++ b/source4/lib/registry/wine.c @@ -1,18 +1,18 @@ -/* +/* Unix SMB/CIFS implementation. Registry interface Copyright (C) Jelmer Vernooij 2007. - + 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 3 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, see <http://www.gnu.org/licenses/>. */ @@ -29,7 +29,7 @@ static WERROR wine_open_reg (struct registry_hive *h, struct registry_key **key) static REG_OPS reg_backend_wine = { .name = "wine", .open_hive = wine_open_reg, - + }; NTSTATUS registry_wine_init(void) diff --git a/source4/lib/replace/README b/source4/lib/replace/README index 77558b2ca9..c61f78a951 100644 --- a/source4/lib/replace/README +++ b/source4/lib/replace/README @@ -50,10 +50,16 @@ pwrite getpass readline (the library) inet_ntoa +inet_ntop +inet_pton strtoll strtoull socketpair strptime +getaddrinfo +freeaddrinfo +getnameinfo +gai_strerror Types: bool diff --git a/source4/lib/replace/configure.ac b/source4/lib/replace/configure.ac index 48fb7ce259..beeb77e152 100644 --- a/source4/lib/replace/configure.ac +++ b/source4/lib/replace/configure.ac @@ -19,4 +19,6 @@ if test "$ac_cv_prog_gcc" = yes; then CFLAGS="$CFLAGS -Wno-format-y2k" fi +AC_SUBST(LDFLAGS) + AC_OUTPUT(Makefile) diff --git a/source4/lib/replace/dlfcn.m4 b/source4/lib/replace/dlfcn.m4 index a1b57d10ec..c5b7597d7a 100644 --- a/source4/lib/replace/dlfcn.m4 +++ b/source4/lib/replace/dlfcn.m4 @@ -12,7 +12,7 @@ AC_VERIFY_C_PROTOTYPE([void *dlopen(const char* filename, unsigned int flags)], [ return 0; ],[ - AC_DEFINE(DLOPEN_TAKES_UNSIGNED_FLAGS, 1, [Whether dlopen takes unsinged int flags]) + AC_DEFINE(DLOPEN_TAKES_UNSIGNED_FLAGS, 1, [Whether dlopen takes unsigned int flags]) ],[],[ #include <dlfcn.h> ]) diff --git a/source4/lib/replace/getaddrinfo.c b/source4/lib/replace/getaddrinfo.c new file mode 100644 index 0000000000..519c30066b --- /dev/null +++ b/source4/lib/replace/getaddrinfo.c @@ -0,0 +1,502 @@ +/* +PostgreSQL Database Management System +(formerly known as Postgres, then as Postgres95) + +Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group + +Portions Copyright (c) 1994, The Regents of the University of California + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose, without fee, and without a written agreement +is hereby granted, provided that the above copyright notice and this paragraph +and the following two paragraphs appear in all copies. + +IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR +DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING +LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, +EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +*/ + +/*------------------------------------------------------------------------- + * + * getaddrinfo.c + * Support getaddrinfo() on platforms that don't have it. + * + * We also supply getnameinfo() here, assuming that the platform will have + * it if and only if it has getaddrinfo(). If this proves false on some + * platform, we'll need to split this file and provide a separate configure + * test for getnameinfo(). + * + * Copyright (c) 2003-2007, PostgreSQL Global Development Group + * + * Copyright (C) 2007 Jeremy Allison. + * Modified to return multiple IPv4 addresses for Samba. + * + *------------------------------------------------------------------------- + */ + +#include "replace.h" +#include "system/network.h" + +#ifndef SMB_MALLOC +#define SMB_MALLOC(s) malloc(s) +#endif + +#ifndef SMB_STRDUP +#define SMB_STRDUP(s) strdup(s) +#endif + +static int check_hostent_err(struct hostent *hp) +{ + if (!hp) { + switch (h_errno) { + case HOST_NOT_FOUND: + case NO_DATA: + return EAI_NONAME; + case TRY_AGAIN: + return EAI_AGAIN; + case NO_RECOVERY: + default: + return EAI_FAIL; + } + } + if (!hp->h_name || hp->h_addrtype != AF_INET) { + return EAI_FAIL; + } + return 0; +} + +static char *canon_name_from_hostent(struct hostent *hp, + int *perr) +{ + char *ret = NULL; + + *perr = check_hostent_err(hp); + if (*perr) { + return NULL; + } + ret = SMB_STRDUP(hp->h_name); + if (!ret) { + *perr = EAI_MEMORY; + } + return ret; +} + +static char *get_my_canon_name(int *perr) +{ + char name[HOST_NAME_MAX+1]; + + if (gethostname(name, HOST_NAME_MAX) == -1) { + *perr = EAI_FAIL; + return NULL; + } + /* Ensure null termination. */ + name[HOST_NAME_MAX] = '\0'; + return canon_name_from_hostent(gethostbyname(name), perr); +} + +static char *get_canon_name_from_addr(struct in_addr ip, + int *perr) +{ + return canon_name_from_hostent( + gethostbyaddr(&ip, sizeof(ip), AF_INET), + perr); +} + +static struct addrinfo *alloc_entry(const struct addrinfo *hints, + struct in_addr ip, + unsigned short port) +{ + struct sockaddr_in *psin = NULL; + struct addrinfo *ai = SMB_MALLOC(sizeof(*ai)); + + if (!ai) { + return NULL; + } + memset(ai, '\0', sizeof(*ai)); + + psin = SMB_MALLOC(sizeof(*psin)); + if (!psin) { + free(ai); + return NULL; + } + + memset(psin, '\0', sizeof(*psin)); + + psin->sin_family = AF_INET; + psin->sin_port = htons(port); + psin->sin_addr = ip; + + ai->ai_flags = 0; + ai->ai_family = AF_INET; + ai->ai_socktype = hints->ai_socktype; + ai->ai_protocol = hints->ai_protocol; + ai->ai_addrlen = sizeof(*psin); + ai->ai_addr = (struct sockaddr *) psin; + ai->ai_canonname = NULL; + ai->ai_next = NULL; + + return ai; +} + +/* + * get address info for a single ipv4 address. + * + * Bugs: - servname can only be a number, not text. + */ + +static int getaddr_info_single_addr(const char *service, + uint32_t addr, + const struct addrinfo *hints, + struct addrinfo **res) +{ + + struct addrinfo *ai = NULL; + struct in_addr ip; + unsigned short port = 0; + + if (service) { + port = (unsigned short)atoi(service); + } + ip.s_addr = htonl(addr); + + ai = alloc_entry(hints, ip, port); + if (!ai) { + return EAI_MEMORY; + } + + /* If we're asked for the canonical name, + * make sure it returns correctly. */ + if (!(hints->ai_flags & AI_NUMERICSERV) && + hints->ai_flags & AI_CANONNAME) { + int err; + if (addr == INADDR_LOOPBACK || addr == INADDR_ANY) { + ai->ai_canonname = get_my_canon_name(&err); + } else { + ai->ai_canonname = + get_canon_name_from_addr(ip,&err); + } + if (ai->ai_canonname == NULL) { + freeaddrinfo(ai); + return err; + } + } + + *res = ai; + return 0; +} + +/* + * get address info for multiple ipv4 addresses. + * + * Bugs: - servname can only be a number, not text. + */ + +static int getaddr_info_name(const char *node, + const char *service, + const struct addrinfo *hints, + struct addrinfo **res) +{ + struct addrinfo *listp = NULL, *prevp = NULL; + char **pptr = NULL; + int err; + struct hostent *hp = NULL; + unsigned short port = 0; + + if (service) { + port = (unsigned short)atoi(service); + } + + hp = gethostbyname(node); + err = check_hostent_err(hp); + if (err) { + return err; + } + + for(pptr = hp->h_addr_list; *pptr; pptr++) { + struct in_addr ip = *(struct in_addr *)pptr; + struct addrinfo *ai = alloc_entry(hints, ip, port); + + if (!ai) { + freeaddrinfo(listp); + return EAI_MEMORY; + } + + if (!listp) { + listp = ai; + prevp = ai; + ai->ai_canonname = SMB_STRDUP(hp->h_name); + if (!ai->ai_canonname) { + freeaddrinfo(listp); + return EAI_MEMORY; + } + } else { + prevp->ai_next = ai; + prevp = ai; + } + } + *res = listp; + return 0; +} + +/* + * get address info for ipv4 sockets. + * + * Bugs: - servname can only be a number, not text. + */ + +int getaddrinfo(const char *node, + const char *service, + const struct addrinfo * hintp, + struct addrinfo ** res) +{ + struct addrinfo hints; + + /* Setup the hints struct. */ + if (hintp == NULL) { + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + } else { + memcpy(&hints, hintp, sizeof(hints)); + } + + if (hints.ai_family != AF_INET && hints.ai_family != AF_UNSPEC) { + return EAI_FAMILY; + } + + if (hints.ai_socktype == 0) { + hints.ai_socktype = SOCK_STREAM; + } + + if (!node && !service) { + return EAI_NONAME; + } + + if (node) { + if (node[0] == '\0') { + return getaddr_info_single_addr(service, + INADDR_ANY, + &hints, + res); + } else if (hints.ai_flags & AI_NUMERICHOST) { + struct in_addr ip; + if (!inet_aton(node, &ip)) { + return EAI_FAIL; + } + return getaddr_info_single_addr(service, + ntohl(ip.s_addr), + &hints, + res); + } else { + return getaddr_info_name(node, + service, + &hints, + res); + } + } else if (hints.ai_flags & AI_PASSIVE) { + return getaddr_info_single_addr(service, + INADDR_ANY, + &hints, + res); + } + return getaddr_info_single_addr(service, + INADDR_LOOPBACK, + &hints, + res); +} + + +void freeaddrinfo(struct addrinfo *res) +{ + struct addrinfo *next = NULL; + + for (;res; res = next) { + next = res->ai_next; + if (res->ai_canonname) { + free(res->ai_canonname); + } + if (res->ai_addr) { + free(res->ai_addr); + } + free(res); + } +} + + +const char *gai_strerror(int errcode) +{ +#ifdef HAVE_HSTRERROR + int hcode; + + switch (errcode) + { + case EAI_NONAME: + hcode = HOST_NOT_FOUND; + break; + case EAI_AGAIN: + hcode = TRY_AGAIN; + break; + case EAI_FAIL: + default: + hcode = NO_RECOVERY; + break; + } + + return hstrerror(hcode); +#else /* !HAVE_HSTRERROR */ + + switch (errcode) + { + case EAI_NONAME: + return "Unknown host"; + case EAI_AGAIN: + return "Host name lookup failure"; +#ifdef EAI_BADFLAGS + case EAI_BADFLAGS: + return "Invalid argument"; +#endif +#ifdef EAI_FAMILY + case EAI_FAMILY: + return "Address family not supported"; +#endif +#ifdef EAI_MEMORY + case EAI_MEMORY: + return "Not enough memory"; +#endif +#ifdef EAI_NODATA + case EAI_NODATA: + return "No host data of that type was found"; +#endif +#ifdef EAI_SERVICE + case EAI_SERVICE: + return "Class type not found"; +#endif +#ifdef EAI_SOCKTYPE + case EAI_SOCKTYPE: + return "Socket type not supported"; +#endif + default: + return "Unknown server error"; + } +#endif /* HAVE_HSTRERROR */ +} + +static int gethostnameinfo(const struct sockaddr *sa, + char *node, + size_t nodelen, + int flags) +{ + int ret = -1; + char *p = NULL; + + if (!(flags & NI_NUMERICHOST)) { + struct hostent *hp = gethostbyaddr( + &((struct sockaddr_in *)sa)->sin_addr, + sizeof(struct in_addr), + sa->sa_family); + ret = check_hostent_err(hp); + if (ret == 0) { + /* Name looked up successfully. */ + ret = snprintf(node, nodelen, "%s", hp->h_name); + if (ret == -1 || ret > nodelen) { + return EAI_MEMORY; + } + if (flags & NI_NOFQDN) { + p = strchr(node,'.'); + if (p) { + *p = '\0'; + } + } + return 0; + } + + if (flags & NI_NAMEREQD) { + /* If we require a name and didn't get one, + * automatically fail. */ + return ret; + } + /* Otherwise just fall into the numeric host code... */ + } + p = inet_ntoa(((struct sockaddr_in *)sa)->sin_addr); + ret = snprintf(node, nodelen, "%s", p); + if (ret == -1 || ret > nodelen) { + return EAI_MEMORY; + } + return 0; +} + +static int getservicenameinfo(const struct sockaddr *sa, + char *service, + size_t servicelen, + int flags) +{ + int ret = -1; + int port = ntohs(((struct sockaddr_in *)sa)->sin_port); + + if (!(flags & NI_NUMERICSERV)) { + struct servent *se = getservbyport( + port, + (flags & NI_DGRAM) ? "udp" : "tcp"); + if (se && se->s_name) { + /* Service name looked up successfully. */ + ret = snprintf(service, servicelen, "%s", se->s_name); + if (ret == -1 || ret > servicelen) { + return EAI_MEMORY; + } + return 0; + } + /* Otherwise just fall into the numeric service code... */ + } + ret = snprintf(service, servicelen, "%d", port); + if (ret == -1 || ret > servicelen) { + return EAI_MEMORY; + } + return 0; +} + +/* + * Convert an ipv4 address to a hostname. + * + * Bugs: - No IPv6 support. + */ +int getnameinfo(const struct sockaddr *sa, socklen_t salen, + char *node, size_t nodelen, + char *service, size_t servicelen, int flags) +{ + + /* Invalid arguments. */ + if (sa == NULL || (node == NULL && service == NULL)) { + return EAI_FAIL; + } + + if (sa->sa_family != AF_INET) { + return EAI_FAIL; + } + + if (salen < sizeof(struct sockaddr_in)) { + return EAI_FAIL; + } + + /* We don't support those. */ + if ((node && !(flags & NI_NUMERICHOST)) + || (service && !(flags & NI_NUMERICSERV))) + return EAI_FAIL; + + if (node) { + return gethostnameinfo(sa, node, nodelen, flags); + } + + if (service) { + return getservicenameinfo(sa, service, servicelen, flags); + } + return 0; +} diff --git a/source4/lib/replace/getaddrinfo.h b/source4/lib/replace/getaddrinfo.h new file mode 100644 index 0000000000..ed678bd065 --- /dev/null +++ b/source4/lib/replace/getaddrinfo.h @@ -0,0 +1,158 @@ +/* +PostgreSQL Database Management System +(formerly known as Postgres, then as Postgres95) + +Portions Copyright (c) 1996-2005, The PostgreSQL Global Development Group + +Portions Copyright (c) 1994, The Regents of the University of California + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose, without fee, and without a written agreement +is hereby granted, provided that the above copyright notice and this paragraph +and the following two paragraphs appear in all copies. + +IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR +DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING +LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, +EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS +ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS +TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +*/ + +/*------------------------------------------------------------------------- + * + * getaddrinfo.h + * Support getaddrinfo() on platforms that don't have it. + * + * Note: we use our own routines on platforms that don't HAVE_STRUCT_ADDRINFO, + * whether or not the library routine getaddrinfo() can be found. This + * policy is needed because on some platforms a manually installed libbind.a + * may provide getaddrinfo(), yet the system headers may not provide the + * struct definitions needed to call it. To avoid conflict with the libbind + * definition in such cases, we rename our routines to pg_xxx() via macros. + * + * This code will also work on platforms where struct addrinfo is defined + * in the system headers but no getaddrinfo() can be located. + * + * Copyright (c) 2003-2007, PostgreSQL Global Development Group + * + *------------------------------------------------------------------------- + */ +#ifndef GETADDRINFO_H +#define GETADDRINFO_H + + +/* Various macros that ought to be in <netdb.h>, but might not be */ + +#ifndef EAI_FAIL +#define EAI_BADFLAGS (-1) +#define EAI_NONAME (-2) +#define EAI_AGAIN (-3) +#define EAI_FAIL (-4) +#define EAI_FAMILY (-6) +#define EAI_SOCKTYPE (-7) +#define EAI_SERVICE (-8) +#define EAI_MEMORY (-10) +#define EAI_SYSTEM (-11) +#endif /* !EAI_FAIL */ + +#ifndef AI_PASSIVE +#define AI_PASSIVE 0x0001 +#endif + +#ifndef AI_NUMERICHOST +/* + * some platforms don't support AI_NUMERICHOST; define as zero if using + * the system version of getaddrinfo... + */ +#if defined(HAVE_STRUCT_ADDRINFO) && defined(HAVE_GETADDRINFO) +#define AI_NUMERICHOST 0 +#else +#define AI_NUMERICHOST 0x0004 +#endif +#endif + +#ifndef NI_NUMERICHOST +#define NI_NUMERICHOST 1 +#endif + +#ifndef NI_NUMERICSERV +#define NI_NUMERICSERV 2 +#endif + +#ifndef NI_NOFQDN +#define NI_NOFQDN 4 +#endif + +#ifndef NI_NAMEREQD +#define NI_NAMEREQD 8 +#endif + +#ifndef NI_DGRAM +#define NI_DGRAM 16 +#endif + + +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#endif + +#ifndef NI_MAXSERV +#define NI_MAXSERV 32 +#endif + +#ifndef HAVE_STRUCT_ADDRINFO + +struct addrinfo +{ + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + size_t ai_addrlen; + struct sockaddr *ai_addr; + char *ai_canonname; + struct addrinfo *ai_next; +}; +#endif /* HAVE_STRUCT_ADDRINFO */ + + +#ifndef HAVE_GETADDRINFO + +/* Rename private copies per comments above */ +#ifdef getaddrinfo +#undef getaddrinfo +#endif +#define getaddrinfo pg_getaddrinfo + +#ifdef freeaddrinfo +#undef freeaddrinfo +#endif +#define freeaddrinfo pg_freeaddrinfo + +#ifdef gai_strerror +#undef gai_strerror +#endif +#define gai_strerror pg_gai_strerror + +#ifdef getnameinfo +#undef getnameinfo +#endif +#define getnameinfo pg_getnameinfo + +extern int getaddrinfo(const char *node, const char *service, + const struct addrinfo * hints, struct addrinfo ** res); +extern void freeaddrinfo(struct addrinfo * res); +extern const char *gai_strerror(int errcode); +extern int getnameinfo(const struct sockaddr * sa, socklen_t salen, + char *node, size_t nodelen, + char *service, size_t servicelen, int flags); +#endif /* HAVE_GETADDRINFO */ + +#endif /* GETADDRINFO_H */ diff --git a/source4/lib/replace/inet_ntop.c b/source4/lib/replace/inet_ntop.c new file mode 100644 index 0000000000..fb3d8e90c8 --- /dev/null +++ b/source4/lib/replace/inet_ntop.c @@ -0,0 +1,191 @@ +/* + * Copyright (C) 1996-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + + +#include "replace.h" +#include "system/network.h" + +#define NS_INT16SZ 2 +#define NS_IN6ADDRSZ 16 + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static const char *inet_ntop4(const unsigned char *src, char *dst, + socklen_t size); + +#ifdef AF_INET6 +static const char *inet_ntop6(const unsigned char *src, char *dst, + socklen_t size); +#endif + +/* char * + * isc_net_ntop(af, src, dst, size) + * convert a network format address to presentation format. + * return: + * pointer to presentation format address (`dst'), or NULL (see errno). + * author: + * Paul Vixie, 1996. + */ +const char * +rep_inet_ntop(int af, const void *src, char *dst, socklen_t size) +{ + switch (af) { + case AF_INET: + return (inet_ntop4(src, dst, size)); +#ifdef AF_INET6 + case AF_INET6: + return (inet_ntop6(src, dst, size)); +#endif + default: + errno = EAFNOSUPPORT; + return (NULL); + } + /* NOTREACHED */ +} + +/* const char * + * inet_ntop4(src, dst, size) + * format an IPv4 address + * return: + * `dst' (as a const) + * notes: + * (1) uses no statics + * (2) takes a unsigned char* not an in_addr as input + * author: + * Paul Vixie, 1996. + */ +static const char * +inet_ntop4(const unsigned char *src, char *dst, socklen_t size) +{ + static const char *fmt = "%u.%u.%u.%u"; + char tmp[sizeof "255.255.255.255"]; + size_t len; + + len = snprintf(tmp, sizeof tmp, fmt, src[0], src[1], src[2], src[3]); + if (len >= size) { + errno = ENOSPC; + return (NULL); + } + memcpy(dst, tmp, len + 1); + + return (dst); +} + +/* const char * + * isc_inet_ntop6(src, dst, size) + * convert IPv6 binary address into presentation (printable) format + * author: + * Paul Vixie, 1996. + */ +#ifdef AF_INET6 +static const char * +inet_ntop6(const unsigned char *src, char *dst, socklen_t size) +{ + /* + * Note that int32_t and int16_t need only be "at least" large enough + * to contain a value of the specified size. On some systems, like + * Crays, there is no such thing as an integer variable with 16 bits. + * Keep this in mind if you think this function should have been coded + * to use pointer overlays. All the world's not a VAX. + */ + char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; + struct { int base, len; } best, cur; + unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ]; + int i, inc; + + /* + * Preprocess: + * Copy the input (bytewise) array into a wordwise array. + * Find the longest run of 0x00's in src[] for :: shorthanding. + */ + memset(words, '\0', sizeof words); + for (i = 0; i < NS_IN6ADDRSZ; i++) + words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); + best.base = -1; + best.len = 0; + cur.base = -1; + cur.len = 0; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + if (words[i] == 0) { + if (cur.base == -1) + cur.base = i, cur.len = 1; + else + cur.len++; + } else { + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + cur.base = -1; + } + } + } + if (cur.base != -1) { + if (best.base == -1 || cur.len > best.len) + best = cur; + } + if (best.base != -1 && best.len < 2) + best.base = -1; + + /* + * Format the result. + */ + tp = tmp; + for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { + /* Are we inside the best run of 0x00's? */ + if (best.base != -1 && i >= best.base && + i < (best.base + best.len)) { + if (i == best.base) + *tp++ = ':'; + continue; + } + /* Are we following an initial run of 0x00s or any real hex? */ + if (i != 0) + *tp++ = ':'; + /* Is this address an encapsulated IPv4? */ + if (i == 6 && best.base == 0 && + (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { + if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) + return (NULL); + tp += strlen(tp); + break; + } + inc = snprintf(tp, 5, "%x", words[i]); + if (inc >= 5) { + abort(); + } + tp += inc; + } + /* Was it a trailing run of 0x00's? */ + if (best.base != -1 && (best.base + best.len) == + (NS_IN6ADDRSZ / NS_INT16SZ)) + *tp++ = ':'; + *tp++ = '\0'; + + /* + * Check for overflow, copy, and we're done. + */ + if ((size_t)(tp - tmp) > size) { + errno = ENOSPC; + return (NULL); + } + memcpy(dst, tmp, tp - tmp); + return (dst); +} +#endif /* AF_INET6 */ diff --git a/source4/lib/replace/inet_ntop.m4 b/source4/lib/replace/inet_ntop.m4 new file mode 100644 index 0000000000..6f39056f1d --- /dev/null +++ b/source4/lib/replace/inet_ntop.m4 @@ -0,0 +1 @@ +AC_CHECK_FUNCS(inet_ntop,[],[LIBREPLACEOBJ="${LIBREPLACEOBJ} inet_ntop.o"]) diff --git a/source4/lib/replace/inet_pton.c b/source4/lib/replace/inet_pton.c new file mode 100644 index 0000000000..80e4865ef4 --- /dev/null +++ b/source4/lib/replace/inet_pton.c @@ -0,0 +1,213 @@ +/* + * Copyright (C) 1996-2001 Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM + * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL + * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING + * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, + * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION + * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "replace.h" +#include "system/network.h" + +#define NS_INT16SZ 2 +#define NS_INADDRSZ 4 +#define NS_IN6ADDRSZ 16 + +/* + * WARNING: Don't even consider trying to compile this on a system where + * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX. + */ + +static int inet_pton4(const char *src, unsigned char *dst); +#ifdef AF_INET6 +static int inet_pton6(const char *src, unsigned char *dst); +#endif + +/* int + * inet_pton(af, src, dst) + * convert from presentation format (which usually means ASCII printable) + * to network format (which is usually some kind of binary format). + * return: + * 1 if the address was valid for the specified address family + * 0 if the address wasn't valid (`dst' is untouched in this case) + * -1 if some other error occurred (`dst' is untouched in this case, too) + * author: + * Paul Vixie, 1996. + */ +int +rep_inet_pton(int af, + const char *src, + void *dst) +{ + switch (af) { + case AF_INET: + return (inet_pton4(src, dst)); +#ifdef AF_INET6 + case AF_INET6: + return (inet_pton6(src, dst)); +#endif + default: + errno = EAFNOSUPPORT; + return (-1); + } + /* NOTREACHED */ +} + +/* int + * inet_pton4(src, dst) + * like inet_aton() but without all the hexadecimal and shorthand. + * return: + * 1 if `src' is a valid dotted quad, else 0. + * notice: + * does not touch `dst' unless it's returning 1. + * author: + * Paul Vixie, 1996. + */ +static int +inet_pton4(src, dst) + const char *src; + unsigned char *dst; +{ + static const char digits[] = "0123456789"; + int saw_digit, octets, ch; + unsigned char tmp[NS_INADDRSZ], *tp; + + saw_digit = 0; + octets = 0; + *(tp = tmp) = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr(digits, ch)) != NULL) { + unsigned int new = *tp * 10 + (pch - digits); + + if (new > 255) + return (0); + *tp = new; + if (! saw_digit) { + if (++octets > 4) + return (0); + saw_digit = 1; + } + } else if (ch == '.' && saw_digit) { + if (octets == 4) + return (0); + *++tp = 0; + saw_digit = 0; + } else + return (0); + } + if (octets < 4) + return (0); + memcpy(dst, tmp, NS_INADDRSZ); + return (1); +} + +/* int + * inet_pton6(src, dst) + * convert presentation level address to network order binary form. + * return: + * 1 if `src' is a valid [RFC1884 2.2] address, else 0. + * notice: + * (1) does not touch `dst' unless it's returning 1. + * (2) :: in a full address is silently ignored. + * credit: + * inspired by Mark Andrews. + * author: + * Paul Vixie, 1996. + */ +#ifdef AF_INET6 +static int +inet_pton6(src, dst) + const char *src; + unsigned char *dst; +{ + static const char xdigits_l[] = "0123456789abcdef", + xdigits_u[] = "0123456789ABCDEF"; + unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; + const char *xdigits, *curtok; + int ch, saw_xdigit; + unsigned int val; + + memset((tp = tmp), '\0', NS_IN6ADDRSZ); + endp = tp + NS_IN6ADDRSZ; + colonp = NULL; + /* Leading :: requires some special handling. */ + if (*src == ':') + if (*++src != ':') + return (0); + curtok = src; + saw_xdigit = 0; + val = 0; + while ((ch = *src++) != '\0') { + const char *pch; + + if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) + pch = strchr((xdigits = xdigits_u), ch); + if (pch != NULL) { + val <<= 4; + val |= (pch - xdigits); + if (val > 0xffff) + return (0); + saw_xdigit = 1; + continue; + } + if (ch == ':') { + curtok = src; + if (!saw_xdigit) { + if (colonp) + return (0); + colonp = tp; + continue; + } + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (unsigned char) (val >> 8) & 0xff; + *tp++ = (unsigned char) val & 0xff; + saw_xdigit = 0; + val = 0; + continue; + } + if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && + inet_pton4(curtok, tp) > 0) { + tp += NS_INADDRSZ; + saw_xdigit = 0; + break; /* '\0' was seen by inet_pton4(). */ + } + return (0); + } + if (saw_xdigit) { + if (tp + NS_INT16SZ > endp) + return (0); + *tp++ = (unsigned char) (val >> 8) & 0xff; + *tp++ = (unsigned char) val & 0xff; + } + if (colonp != NULL) { + /* + * Since some memmove()'s erroneously fail to handle + * overlapping regions, we'll do the shift by hand. + */ + const int n = tp - colonp; + int i; + + for (i = 1; i <= n; i++) { + endp[- i] = colonp[n - i]; + colonp[n - i] = 0; + } + tp = endp; + } + if (tp != endp) + return (0); + memcpy(dst, tmp, NS_IN6ADDRSZ); + return (1); +} +#endif diff --git a/source4/lib/replace/inet_pton.m4 b/source4/lib/replace/inet_pton.m4 new file mode 100644 index 0000000000..51de9275d0 --- /dev/null +++ b/source4/lib/replace/inet_pton.m4 @@ -0,0 +1 @@ +AC_CHECK_FUNCS(inet_pton,[],[LIBREPLACEOBJ="${LIBREPLACEOBJ} inet_pton.o"]) diff --git a/source4/lib/replace/libreplace.m4 b/source4/lib/replace/libreplace.m4 index f06d7f83dc..4bdbf3a504 100644 --- a/source4/lib/replace/libreplace.m4 +++ b/source4/lib/replace/libreplace.m4 @@ -137,6 +137,55 @@ if test x"$samba_cv_REPLACE_INET_NTOA" = x"yes"; then AC_DEFINE(REPLACE_INET_NTOA,1,[Whether inet_ntoa should be replaced]) fi +dnl test for struct addrinfo +AC_CACHE_CHECK([for struct addrinfo],samba_cv_HAVE_STRUCT_ADDRINFO,[ +AC_TRY_COMPILE([ +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#include <stddef.h> +#endif +#include <sys/socket.h> +#include <netdb.h>], +[ +struct addrinfo ai; +], +samba_cv_HAVE_STRUCT_ADDRINFO=yes,samba_cv_HAVE_STRUCT_ADDRINFO=no)]) +if test x"$samba_cv_HAVE_STRUCT_ADDRINFO" = x"yes"; then + AC_DEFINE(HAVE_STRUCT_ADDRINFO,1,[Whether the system has struct addrinfo]) +fi + +dnl test for getaddrinfo/getnameinfo +AC_CACHE_CHECK([for getaddrinfo],samba_cv_HAVE_GETADDRINFO,[ +AC_TRY_COMPILE([ +#include <sys/types.h> +#if STDC_HEADERS +#include <stdlib.h> +#include <stddef.h> +#endif +#include <sys/socket.h> +#include <netdb.h>], +[ +struct sockaddr sa; +struct addrinfo *ai = NULL; +int ret = getaddrinfo(NULL, NULL, NULL, &ai); +if (ret != 0) { + const char *es = gai_strerror(ret); +} +freeaddrinfo(ai); +ret = getnameinfo(&sa, sizeof(sa), + NULL, 0, + NULL, 0, 0); + +], +samba_cv_HAVE_GETADDRINFO=yes,samba_cv_HAVE_GETADDRINFO=no)]) +if test x"$samba_cv_HAVE_GETADDRINFO" = x"yes"; then + AC_DEFINE(HAVE_GETADDRINFO,1,[Whether the system has getaddrinfo and getnameinfo]) + AC_DEFINE(HAVE_FREEADDRINFO,1,[Whether the system has freeaddrinfo]) + AC_DEFINE(HAVE_GAI_STRERROR,1,[Whether the system has gai_strerror]) +fi + + dnl Provided by replace.c: AC_TRY_COMPILE([ #include <sys/types.h> @@ -152,6 +201,7 @@ AC_CHECK_FUNCS(seteuid setresuid setegid setresgid chroot bzero strerror) AC_CHECK_FUNCS(vsyslog setlinebuf mktime ftruncate chsize rename) AC_CHECK_FUNCS(waitpid strlcpy strlcat initgroups memmove strdup) AC_CHECK_FUNCS(pread pwrite strndup strcasestr strtok_r mkdtemp socketpair) +AC_CHECK_FUNCS(isatty) AC_HAVE_DECL(setresuid, [#include <unistd.h>]) AC_HAVE_DECL(setresgid, [#include <unistd.h>]) AC_HAVE_DECL(errno, [#include <errno.h>]) @@ -303,18 +353,7 @@ AC_TRY_COMPILE([ samba_cv_HAVE_OPEN_O_DIRECT=yes,samba_cv_HAVE_OPEN_O_DIRECT=no)]) if test x"$samba_cv_HAVE_OPEN_O_DIRECT" = x"yes"; then AC_DEFINE(HAVE_OPEN_O_DIRECT,1,[Whether the open(2) accepts O_DIRECT]) -fi - - -AC_CACHE_CHECK([that the C compiler can precompile header files],samba_cv_precompiled_headers, [ - dnl Check whether the compiler can generate precompiled headers - touch conftest.h - if ${CC-cc} conftest.h 2> /dev/null && test -f conftest.h.gch; then - precompiled_headers=yes - else - precompiled_headers=no - fi]) -AC_SUBST(precompiled_headers) +fi dnl Check if the C compiler understands volatile (it should, being ANSI). @@ -332,6 +371,8 @@ m4_include(getpass.m4) m4_include(strptime.m4) m4_include(win32.m4) m4_include(timegm.m4) +m4_include(inet_ntop.m4) +m4_include(inet_pton.m4) m4_include(repdir.m4) AC_CHECK_FUNCS([syslog memset memcpy],,[AC_MSG_ERROR([Required function not found])]) diff --git a/source4/lib/replace/replace.h b/source4/lib/replace/replace.h index 06173bd84b..26e39ac603 100644 --- a/source4/lib/replace/replace.h +++ b/source4/lib/replace/replace.h @@ -1,15 +1,16 @@ -/* +/* Unix SMB/CIFS implementation. macros to go along with the lib/replace/ portability layer code Copyright (C) Andrew Tridgell 2005 Copyright (C) Jelmer Vernooij 2006 + Copyright (C) Jeremy Allison 2007. ** NOTE! The following LGPL license applies to the replace ** library. This does NOT imply that all of Samba is released ** under the LGPL - + This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either @@ -44,13 +45,6 @@ #include "win32_replace.h" #endif -#ifdef __COMPAR_FN_T -#define QSORT_CAST (__compar_fn_t) -#endif - -#ifndef QSORT_CAST -#define QSORT_CAST (int (*)(const void *, const void *)) -#endif #ifdef HAVE_STDINT_H #include <stdint.h> @@ -78,29 +72,6 @@ #include <stddef.h> #endif -/** - this is a warning hack. The idea is to use this everywhere that we - get the "discarding const" warning from gcc. That doesn't actually - fix the problem of course, but it means that when we do get to - cleaning them up we can do it by searching the code for - discard_const. - - It also means that other error types aren't as swamped by the noise - of hundreds of const warnings, so we are more likely to notice when - we get new errors. - - Please only add more uses of this macro when you find it - _really_ hard to fix const warnings. Our aim is to eventually use - this function in only a very few places. - - Also, please call this via the discard_const_p() macro interface, as that - makes the return type safe. -*/ -#define discard_const(ptr) ((void *)((intptr_t)(ptr))) - -/** Type-safe version of discard_const */ -#define discard_const_p(type, ptr) ((type *)discard_const(ptr)) - #ifndef HAVE_STRERROR extern char *sys_errlist[]; #define strerror(i) sys_errlist[i] @@ -168,7 +139,7 @@ int setenv(const char *name, const char *value, int overwrite); #ifndef HAVE_UNSETENV #define unsetenv rep_unsetenv -int rep_unsetenv(const char *name); +int rep_unsetenv(const char *name); #endif #ifndef HAVE_SETEUID @@ -192,7 +163,7 @@ char *rep_strcasestr(const char *haystack, const char *needle); #endif #ifndef HAVE_STRTOK_R -#define strtok_r rep_strtok_r +#define strtok_r rep_strtok_r char *rep_strtok_r(char *s, const char *delim, char **save_ptr); #endif @@ -359,10 +330,25 @@ ssize_t rep_pread(int __fd, void *__buf, size_t __nbytes, off_t __offset); ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset); #endif +#ifndef HAVE_INET_PTON +int rep_inet_pton(int af, const char *src, void *dst); +#define inet_pton rep_inet_pton +#endif + +#ifndef HAVE_INET_NTOP +#include "system/network.h" +const char *rep_inet_ntop(int af, const void *src, char *dst, socklen_t size); +#define inet_ntop rep_inet_ntop +#endif + #ifdef HAVE_LIMITS_H #include <limits.h> #endif +#ifdef HAVE_SYS_PARAM_H +#include <sys/param.h> +#endif + /* The extra casts work around common compiler bugs. */ #define _TYPE_SIGNED(t) (! ((t) 0 < (t) -1)) /* The outer cast is needed to work around a bug in Cray C 5.0.3.0. @@ -375,6 +361,14 @@ ssize_t rep_pwrite(int __fd, const void *__buf, size_t __nbytes, off_t __offset) #define HOST_NAME_MAX 64 #endif +/* + * Some older systems seem not to have MAXHOSTNAMELEN + * defined. + */ +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN HOST_NAME_MAX +#endif + #ifndef UINT16_MAX #define UINT16_MAX 65535 #endif @@ -450,9 +444,6 @@ typedef int bool; #endif #endif -#ifdef HAVE_SYS_PARAM_H -#include <sys/param.h> -#endif #ifndef MIN #define MIN(a,b) ((a)<(b)?(a):(b)) @@ -462,11 +453,34 @@ typedef int bool; #define MAX(a,b) ((a)>(b)?(a):(b)) #endif +/** + this is a warning hack. The idea is to use this everywhere that we + get the "discarding const" warning from gcc. That doesn't actually + fix the problem of course, but it means that when we do get to + cleaning them up we can do it by searching the code for + discard_const. + + It also means that other error types aren't as swamped by the noise + of hundreds of const warnings, so we are more likely to notice when + we get new errors. + + Please only add more uses of this macro when you find it + _really_ hard to fix const warnings. Our aim is to eventually use + this function in only a very few places. + + Also, please call this via the discard_const_p() macro interface, as that + makes the return type safe. +*/ +#define discard_const(ptr) ((void *)((intptr_t)(ptr))) + +/** Type-safe version of discard_const */ +#define discard_const_p(type, ptr) ((type *)discard_const(ptr)) + #ifndef __STRING #define __STRING(x) #x #endif -#ifndef _STRINGSTRING +#ifndef __STRINGSTRING #define __STRINGSTRING(x) __STRING(x) #endif @@ -511,4 +525,12 @@ typedef int bool; #undef HAVE_MMAP #endif +#ifdef __COMPAR_FN_T +#define QSORT_CAST (__compar_fn_t) +#endif + +#ifndef QSORT_CAST +#define QSORT_CAST (int (*)(const void *, const void *)) +#endif + #endif /* _LIBREPLACE_REPLACE_H */ diff --git a/source4/lib/replace/system/network.h b/source4/lib/replace/system/network.h index 13d95a8ba7..02942f9a44 100644 --- a/source4/lib/replace/system/network.h +++ b/source4/lib/replace/system/network.h @@ -49,6 +49,10 @@ #include <netinet/tcp.h> #endif +#if !defined(HAVE_GETADDRINFO) +#include "getaddrinfo.h" +#endif + /* * The next three defines are needed to access the IPTOS_* options * on some systems. @@ -98,14 +102,6 @@ char *rep_inet_ntoa(struct in_addr ip); #define MSG_WAITALL 0 #endif -/* - * Some older systems seem not to have MAXHOSTNAMELEN - * defined. - */ -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 254 -#endif - #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK 0x7f000001 #endif @@ -114,4 +110,8 @@ char *rep_inet_ntoa(struct in_addr ip); #define INADDR_NONE 0xffffffff #endif +#ifndef INET_ADDRSTRLEN +#define INET_ADDRSTRLEN 16 +#endif + #endif diff --git a/source4/lib/samba3/config.mk b/source4/lib/samba3/config.mk index b6441c4dcd..aefb077cf5 100644 --- a/source4/lib/samba3/config.mk +++ b/source4/lib/samba3/config.mk @@ -18,7 +18,6 @@ PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBTDB NDR_SECURITY \ # Start SUBSYSTEM LIBSAMBA3 [SUBSYSTEM::SMBPASSWD] PRIVATE_PROTO_HEADER = samba3_smbpasswd_proto.h -PUBLIC_HEADERS = samba3.h OBJ_FILES = smbpasswd.o # End SUBSYSTEM LIBSAMBA3 ################################################ diff --git a/source4/lib/smbreadline/smbreadline.c b/source4/lib/smbreadline/smbreadline.c index ae9fc4a3b7..2a72750efb 100644 --- a/source4/lib/smbreadline/smbreadline.c +++ b/source4/lib/smbreadline/smbreadline.c @@ -23,6 +23,7 @@ #include "system/filesys.h" #include "system/select.h" #include "system/readline.h" +#include "lib/smbreadline/smbreadline.h" /******************************************************************* Similar to sys_select() but catch EINTR and continue. diff --git a/source4/lib/socket/access.c b/source4/lib/socket/access.c index 2d228c7474..42c42db365 100644 --- a/source4/lib/socket/access.c +++ b/source4/lib/socket/access.c @@ -39,7 +39,7 @@ #define ALLONES ((uint32_t)0xFFFFFFFF) /* masked_match - match address against netnumber/netmask */ -static BOOL masked_match(TALLOC_CTX *mem_ctx, const char *tok, const char *slash, const char *s) +static bool masked_match(TALLOC_CTX *mem_ctx, const char *tok, const char *slash, const char *s) { uint32_t net; uint32_t mask; @@ -47,7 +47,7 @@ static BOOL masked_match(TALLOC_CTX *mem_ctx, const char *tok, const char *slash char *tok_cpy; if ((addr = interpret_addr(s)) == INADDR_NONE) - return False; + return false; tok_cpy = talloc_strdup(mem_ctx, tok); tok_cpy[PTR_DIFF(slash,tok)] = '\0'; @@ -64,14 +64,14 @@ static BOOL masked_match(TALLOC_CTX *mem_ctx, const char *tok, const char *slash if (net == INADDR_NONE || mask == INADDR_NONE) { DEBUG(0,("access: bad net/mask access control: %s\n", tok)); - return False; + return false; } return (addr & mask) == (net & mask); } /* string_match - match string against token */ -static BOOL string_match(TALLOC_CTX *mem_ctx, const char *tok,const char *s, char *invalid_char) +static bool string_match(TALLOC_CTX *mem_ctx, const char *tok,const char *s, char *invalid_char) { size_t tok_len; size_t str_len; @@ -79,50 +79,50 @@ static BOOL string_match(TALLOC_CTX *mem_ctx, const char *tok,const char *s, cha *invalid_char = '\0'; - /* Return True if a token has the magic value "ALL". Return + /* Return true if a token has the magic value "ALL". Return * FAIL if the token is "FAIL". If the token starts with a "." - * (domain name), return True if it matches the last fields of + * (domain name), return true if it matches the last fields of * the string. If the token has the magic value "LOCAL", - * return True if the string does not contain a "." + * return true if the string does not contain a "." * character. If the token ends on a "." (network number), - * return True if it matches the first fields of the + * return true if it matches the first fields of the * string. If the token begins with a "@" (netgroup name), - * return True if the string is a (host) member of the - * netgroup. Return True if the token fully matches the + * return true if the string is a (host) member of the + * netgroup. Return true if the token fully matches the * string. If the token is a netnumber/netmask pair, return - * True if the address is a member of the specified subnet. + * true if the address is a member of the specified subnet. */ if (tok[0] == '.') { /* domain: match last fields */ if ((str_len = strlen(s)) > (tok_len = strlen(tok)) && strcasecmp(tok, s + str_len - tok_len)==0) { - return True; + return true; } } else if (tok[0] == '@') { /* netgroup: look it up */ DEBUG(0,("access: netgroup support is not available\n")); - return False; + return false; } else if (strcmp(tok, "ALL")==0) { /* all: match any */ - return True; + return true; } else if (strcmp(tok, "FAIL")==0) { /* fail: match any */ return FAIL; } else if (strcmp(tok, "LOCAL")==0) { /* local: no dots */ if (strchr(s, '.') == 0 && strcasecmp(s, "unknown") != 0) { - return True; + return true; } } else if (strcasecmp(tok, s)==0) { /* match host name or address */ - return True; + return true; } else if (tok[(tok_len = strlen(tok)) - 1] == '.') { /* network */ if (strncmp(tok, s, tok_len) == 0) - return True; + return true; } else if ((cut = strchr(tok, '/')) != 0) { /* netnumber/netmask */ if (isdigit((int)s[0]) && masked_match(mem_ctx, tok, cut, s)) - return True; + return true; } else if (strchr(tok, '*') != 0) { *invalid_char = '*'; } else if (strchr(tok, '?') != 0) { *invalid_char = '?'; } - return False; + return false; } struct client_addr { @@ -131,9 +131,9 @@ struct client_addr { }; /* client_match - match host name and address against token */ -static BOOL client_match(TALLOC_CTX *mem_ctx, const char *tok, struct client_addr *client) +static bool client_match(TALLOC_CTX *mem_ctx, const char *tok, struct client_addr *client) { - BOOL match; + bool match; char invalid_char = '\0'; /* @@ -158,12 +158,12 @@ token '%s' in an allow/deny hosts line.\n", invalid_char, tok )); } /* list_match - match an item against a list of tokens with exceptions */ -static BOOL list_match(TALLOC_CTX *mem_ctx, const char **list, struct client_addr *client) +static bool list_match(TALLOC_CTX *mem_ctx, const char **list, struct client_addr *client) { - BOOL match = False; + bool match = false; if (!list) - return False; + return false; /* * Process tokens one at a time. We have exhausted all possible matches @@ -175,18 +175,18 @@ static BOOL list_match(TALLOC_CTX *mem_ctx, const char **list, struct client_add for (; *list ; list++) { if (strcmp(*list, "EXCEPT")==0) /* EXCEPT: give up */ break; - if ((match = client_match(mem_ctx, *list, client))) /* True or FAIL */ + if ((match = client_match(mem_ctx, *list, client))) /* true or FAIL */ break; } - /* Process exceptions to True or FAIL matches. */ - if (match != False) { + /* Process exceptions to true or FAIL matches. */ + if (match != false) { while (*list && strcmp(*list, "EXCEPT")!=0) list++; for (; *list; list++) { if (client_match(mem_ctx, *list, client)) /* Exception Found */ - return False; + return false; } } @@ -194,7 +194,7 @@ static BOOL list_match(TALLOC_CTX *mem_ctx, const char **list, struct client_add } /* return true if access should be allowed */ -static BOOL allow_access_internal(TALLOC_CTX *mem_ctx, +static bool allow_access_internal(TALLOC_CTX *mem_ctx, const char **deny_list,const char **allow_list, const char *cname, const char *caddr) { @@ -213,15 +213,15 @@ static BOOL allow_access_internal(TALLOC_CTX *mem_ctx, list_match(mem_ctx, deny_list, &client) && (!allow_list || !list_match(mem_ctx, allow_list, &client))) { - return False; + return false; } - return True; + return true; } /* if theres no deny list and no allow list then allow access */ if ((!deny_list || *deny_list == 0) && (!allow_list || *allow_list == 0)) { - return True; + return true; } /* if there is an allow list but no deny list then allow only hosts @@ -237,27 +237,27 @@ static BOOL allow_access_internal(TALLOC_CTX *mem_ctx, /* if there are both types of list then allow all hosts on the allow list */ if (list_match(mem_ctx, allow_list, &client)) - return True; + return true; /* if there are both types of list and it's not on the allow then allow it if its not on the deny */ if (list_match(mem_ctx, deny_list, &client)) - return False; + return false; - return True; + return true; } /* return true if access should be allowed */ -BOOL allow_access(TALLOC_CTX *mem_ctx, +bool allow_access(TALLOC_CTX *mem_ctx, const char **deny_list, const char **allow_list, const char *cname, const char *caddr) { - BOOL ret; + bool ret; char *nc_cname = talloc_strdup(mem_ctx, cname); char *nc_caddr = talloc_strdup(mem_ctx, caddr); if (!nc_cname || !nc_caddr) { - return False; + return false; } ret = allow_access_internal(mem_ctx, deny_list, allow_list, nc_cname, nc_caddr); @@ -271,12 +271,12 @@ BOOL allow_access(TALLOC_CTX *mem_ctx, /* return true if the char* contains ip addrs only. Used to avoid gethostbyaddr() calls */ -static BOOL only_ipaddrs_in_list(const char** list) +static bool only_ipaddrs_in_list(const char** list) { - BOOL only_ip = True; + bool only_ip = true; if (!list) - return True; + return true; for (; *list ; list++) { /* factor out the special strings */ @@ -293,7 +293,7 @@ static BOOL only_ipaddrs_in_list(const char** list) * have a '/' in them */ if ((strchr(*list, '/')) == NULL) { - only_ip = False; + only_ip = false; DEBUG(3,("only_ipaddrs_in_list: list has non-ip address (%s)\n", *list)); break; } @@ -304,30 +304,30 @@ static BOOL only_ipaddrs_in_list(const char** list) } /* return true if access should be allowed to a service for a socket */ -BOOL socket_check_access(struct socket_context *sock, +bool socket_check_access(struct socket_context *sock, const char *service_name, const char **allow_list, const char **deny_list) { - BOOL ret; + bool ret; const char *name=""; struct socket_address *addr; TALLOC_CTX *mem_ctx; if ((!deny_list || *deny_list==0) && (!allow_list || *allow_list==0)) { - return True; + return true; } mem_ctx = talloc_init("socket_check_access"); if (!mem_ctx) { - return False; + return false; } addr = socket_get_peer_addr(sock, mem_ctx); if (!addr) { DEBUG(0,("socket_check_access: Denied connection from unknown host: could not get peer address from kernel\n")); talloc_free(mem_ctx); - return False; + return false; } /* bypass gethostbyaddr() calls if the lists only contain IP addrs */ @@ -342,7 +342,7 @@ BOOL socket_check_access(struct socket_context *sock, if (!addr) { DEBUG(0,("socket_check_access: Denied connection from unknown host\n")); talloc_free(mem_ctx); - return False; + return false; } ret = allow_access(mem_ctx, deny_list, allow_list, name, addr->addr); diff --git a/source4/lib/socket/config.m4 b/source4/lib/socket/config.m4 index e9c194ddc4..3296730c82 100644 --- a/source4/lib/socket/config.m4 +++ b/source4/lib/socket/config.m4 @@ -41,7 +41,7 @@ SMB_EXT_LIB(EXT_SOCKET,[${SOCKET_LIBS}],[${SOCKET_CFLAGS}],[${SOCKET_CPPFLAGS}], AC_CHECK_FUNCS(gethostbyname) if test x"$ac_cv_func_gethostbyname" = x"no"; then AC_CHECK_LIB_EXT(nsl_s, NSL_LIBS, gethostbyname) - AC_CHECK_LIB_EXT(nsl, NSl_LIBS, gethostbyname) + AC_CHECK_LIB_EXT(nsl, NSL_LIBS, gethostbyname) AC_CHECK_LIB_EXT(socket, NSL_LIBS, gethostbyname) SMB_ENABLE(EXT_NSL,YES) dnl We can't just call AC_CHECK_FUNCS(gethostbyname) here, because the value @@ -102,8 +102,10 @@ dnl the configure uses --with-static-modules=socket_ipv6 # # This tests need LIBS="$NSL_LIBS $SOCKET_LIBS" # +old_CFLAGS=$CFLAGS old_LIBS=$LIBS LIBS="$NSL_LIBS $SOCKET_LIBS" +CFLAGS="$CFLAGS -Ilib/replace" iface=no; AC_CACHE_CHECK([for iface AIX],samba_cv_HAVE_IFACE_AIX,[ AC_TRY_RUN([ @@ -140,4 +142,5 @@ if test x"$samba_cv_HAVE_IFACE_IFREQ" = x"yes"; then fi fi +CFLAGS=$old_CFLAGS LIBS=$old_LIBS diff --git a/source4/lib/socket/config.mk b/source4/lib/socket/config.mk index 22037cd136..d1e0bcfef5 100644 --- a/source4/lib/socket/config.mk +++ b/source4/lib/socket/config.mk @@ -10,25 +10,14 @@ PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL EXT_SOCKET EXT_NSL ############################## ################################################ -# Start MODULE socket_ipv4 -[MODULE::socket_ipv4] +# Start MODULE socket_ip +[MODULE::socket_ip] SUBSYSTEM = samba-socket OUTPUT_TYPE = INTEGRATED OBJ_FILES = \ - socket_ipv4.o + socket_ip.o PRIVATE_DEPENDENCIES = EXT_SOCKET EXT_NSL LIBSAMBA-ERRORS -# End MODULE socket_ipv4 -################################################ - -################################################ -# Start MODULE socket_ipv6 -[MODULE::socket_ipv6] -SUBSYSTEM = samba-socket -OUTPUT_TYPE = INTEGRATED -OBJ_FILES = \ - socket_ipv6.o -PRIVATE_DEPENDENCIES = EXT_SOCKET EXT_NSL -# End MODULE socket_ipv6 +# End MODULE socket_ip ################################################ ################################################ diff --git a/source4/lib/socket/connect.c b/source4/lib/socket/connect.c index dd2440b0a8..4a30fa3b92 100644 --- a/source4/lib/socket/connect.c +++ b/source4/lib/socket/connect.c @@ -26,6 +26,7 @@ #include "lib/events/events.h" #include "libcli/composite/composite.h" #include "libcli/resolve/resolve.h" +#include "param/param.h" struct connect_state { @@ -119,14 +120,14 @@ struct composite_context *socket_connect_send(struct socket_context *sock, state->flags = flags; - set_blocking(socket_get_fd(sock), False); + set_blocking(socket_get_fd(sock), false); if (server_address->addr && strcmp(sock->backend_name, "ipv4") == 0) { struct nbt_name name; struct composite_context *creq; make_nbt_name_client(&name, server_address->addr); creq = resolve_name_send(&name, result->event_ctx, - lp_name_resolve_order()); + lp_name_resolve_order(global_loadparm)); if (composite_nomem(creq, result)) return result; composite_continue(result, creq, continue_resolve_name, result); return result; diff --git a/source4/lib/socket/connect_multi.c b/source4/lib/socket/connect_multi.c index 76e5034a58..6d30141459 100644 --- a/source4/lib/socket/connect_multi.c +++ b/source4/lib/socket/connect_multi.c @@ -26,6 +26,7 @@ #include "lib/events/events.h" #include "libcli/composite/composite.h" #include "libcli/resolve/resolve.h" +#include "param/param.h" #define MULTI_PORT_DELAY 2000 /* microseconds */ @@ -62,7 +63,8 @@ static void continue_one(struct composite_context *creq); /* setup an async socket_connect, with multiple ports */ -_PUBLIC_ struct composite_context *socket_connect_multi_send(TALLOC_CTX *mem_ctx, +_PUBLIC_ struct composite_context *socket_connect_multi_send( + TALLOC_CTX *mem_ctx, const char *server_address, int num_server_ports, uint16_t *server_ports, @@ -102,7 +104,7 @@ _PUBLIC_ struct composite_context *socket_connect_multi_send(TALLOC_CTX *mem_ctx struct composite_context *creq; make_nbt_name_client(&name, server_address); creq = resolve_name_send(&name, result->event_ctx, - lp_name_resolve_order()); + lp_name_resolve_order(global_loadparm)); if (composite_nomem(creq, result)) goto failed; composite_continue(result, creq, continue_resolve_name, result); return result; diff --git a/source4/lib/socket/interface.c b/source4/lib/socket/interface.c index 58d00ba614..9ca4450581 100644 --- a/source4/lib/socket/interface.c +++ b/source4/lib/socket/interface.c @@ -23,6 +23,7 @@ #include "system/network.h" #include "lib/socket/netif.h" #include "lib/util/dlinklist.h" +#include "param/param.h" /** used for network interfaces */ struct interface { @@ -53,7 +54,7 @@ static struct ipv4_addr tov4(struct in_addr in) /**************************************************************************** Try and find an interface that matches an ip. If we cannot, return NULL **************************************************************************/ -static struct interface *iface_find(struct in_addr ip, BOOL CheckMask) +static struct interface *iface_find(struct in_addr ip, bool CheckMask) { struct interface *i; if (is_zero_ip(tov4(ip))) return local_interfaces; @@ -74,12 +75,13 @@ static void add_interface(struct in_addr ip, struct in_addr nmask) { struct interface *iface; struct ipv4_addr bcast; - if (iface_find(ip, False)) { + + if (iface_find(ip, false)) { DEBUG(3,("not adding duplicate interface %s\n",inet_ntoa(ip))); return; } - iface = talloc(local_interfaces, struct interface); + iface = talloc(local_interfaces == NULL ? talloc_autofree_context() : local_interfaces, struct interface); if (!iface) return; ZERO_STRUCTPN(iface); @@ -198,7 +200,7 @@ static void load_interfaces(void) return; } - ptr = lp_interfaces(); + ptr = lp_interfaces(global_loadparm); loopback_ip = interpret_addr2("127.0.0.1"); /* probe the kernel for interfaces */ @@ -319,7 +321,7 @@ const char *iface_best_ip(const char *dest) load_interfaces(); ip.s_addr = interpret_addr(dest); - iface = iface_find(ip, True); + iface = iface_find(ip, true); if (iface) { return iface->ip_s; } @@ -327,25 +329,25 @@ const char *iface_best_ip(const char *dest) } /** - return True if an IP is one one of our local networks + return true if an IP is one one of our local networks */ -BOOL iface_is_local(const char *dest) +bool iface_is_local(const char *dest) { struct in_addr ip; load_interfaces(); ip.s_addr = interpret_addr(dest); - if (iface_find(ip, True)) { - return True; + if (iface_find(ip, true)) { + return true; } - return False; + return false; } /** - return True if a IP matches a IP/netmask pair + return true if a IP matches a IP/netmask pair */ -BOOL iface_same_net(const char *ip1, const char *ip2, const char *netmask) +bool iface_same_net(const char *ip1, const char *ip2, const char *netmask) { return same_net(interpret_addr2(ip1), interpret_addr2(ip2), diff --git a/source4/lib/socket/netif.h b/source4/lib/socket/netif.h index dea7476193..4855f4bd73 100644 --- a/source4/lib/socket/netif.h +++ b/source4/lib/socket/netif.h @@ -19,6 +19,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include "system/network.h" + struct iface_struct { char name[16]; struct in_addr ip; diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index a60171ccd1..92f0a44005 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -23,6 +23,7 @@ #include "lib/socket/socket.h" #include "system/filesys.h" #include "system/network.h" +#include "param/param.h" /* auto-close sockets on free @@ -69,14 +70,14 @@ _PUBLIC_ NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socke if (!(flags & SOCKET_FLAG_BLOCK) && type == SOCKET_TYPE_STREAM && - lp_parm_bool(-1, "socket", "testnonblock", False)) { + lp_parm_bool(global_loadparm, NULL, "socket", "testnonblock", false)) { (*new_sock)->flags |= SOCKET_FLAG_TESTNONBLOCK; } /* we don't do a connect() on dgram sockets, so need to set non-blocking at socket create time */ if (!(flags & SOCKET_FLAG_BLOCK) && type == SOCKET_TYPE_DGRAM) { - set_blocking(socket_get_fd(*new_sock), False); + set_blocking(socket_get_fd(*new_sock), false); } talloc_set_destructor(*new_sock, socket_destructor); @@ -407,7 +408,7 @@ _PUBLIC_ struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx addr->family = NULL; addr->addr = NULL; addr->port = 0; - addr->sockaddr = talloc_memdup(addr, sockaddr, sockaddrlen); + addr->sockaddr = (struct sockaddr *)talloc_memdup(addr, sockaddr, sockaddrlen); if (!addr->sockaddr) { talloc_free(addr); return NULL; @@ -429,10 +430,6 @@ _PUBLIC_ const struct socket_ops *socket_getops_byname(const char *family, enum #if HAVE_IPV6 if (strcmp("ipv6", family) == 0) { - if (lp_parm_bool(-1, "socket", "noipv6", False)) { - DEBUG(3, ("IPv6 support was disabled in smb.conf")); - return NULL; - } return socket_ipv6_ops(type); } #endif @@ -505,12 +502,12 @@ _PUBLIC_ void set_socket_options(int fd, const char *options) int ret=0,i; int value = 1; char *p; - BOOL got_value = False; + bool got_value = false; if ((p = strchr(tok,'='))) { *p = 0; value = atoi(p+1); - got_value = True; + got_value = true; } for (i=0;socket_options[i].name;i++) diff --git a/source4/lib/socket/socket.h b/source4/lib/socket/socket.h index 0c4fc0bb95..7679db08a1 100644 --- a/source4/lib/socket/socket.h +++ b/source4/lib/socket/socket.h @@ -121,6 +121,9 @@ struct socket_context { void *private_data; const struct socket_ops *ops; const char *backend_name; + + /* specific to the ip backend */ + int family; }; diff --git a/source4/lib/socket/socket_ip.c b/source4/lib/socket/socket_ip.c new file mode 100644 index 0000000000..499dc93d7b --- /dev/null +++ b/source4/lib/socket/socket_ip.c @@ -0,0 +1,981 @@ +/* + Unix SMB/CIFS implementation. + + Socket IPv4/IPv6 functions + + Copyright (C) Stefan Metzmacher 2004 + Copyright (C) Andrew Tridgell 2004-2005 + Copyright (C) Jelmer Vernooij 2004 + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "system/filesys.h" +#include "lib/socket/socket.h" +#include "system/network.h" + +static NTSTATUS ipv4_init(struct socket_context *sock) +{ + int type; + + switch (sock->type) { + case SOCKET_TYPE_STREAM: + type = SOCK_STREAM; + break; + case SOCKET_TYPE_DGRAM: + type = SOCK_DGRAM; + break; + default: + return NT_STATUS_INVALID_PARAMETER; + } + + sock->fd = socket(PF_INET, type, 0); + if (sock->fd == -1) { + return map_nt_error_from_unix(errno); + } + + sock->backend_name = "ipv4"; + sock->family = AF_INET; + + return NT_STATUS_OK; +} + +static void ip_close(struct socket_context *sock) +{ + close(sock->fd); +} + +static NTSTATUS ip_connect_complete(struct socket_context *sock, uint32_t flags) +{ + int error=0, ret; + socklen_t len = sizeof(error); + + /* check for any errors that may have occurred - this is needed + for non-blocking connect */ + ret = getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, &error, &len); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + if (error != 0) { + return map_nt_error_from_unix(error); + } + + if (!(flags & SOCKET_FLAG_BLOCK)) { + ret = set_blocking(sock->fd, false); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + } + + sock->state = SOCKET_STATE_CLIENT_CONNECTED; + + return NT_STATUS_OK; +} + + +static NTSTATUS ipv4_connect(struct socket_context *sock, + const struct socket_address *my_address, + const struct socket_address *srv_address, + uint32_t flags) +{ + struct sockaddr_in srv_addr; + struct ipv4_addr my_ip; + struct ipv4_addr srv_ip; + int ret; + + if (my_address && my_address->sockaddr) { + ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + } else if (my_address) { + my_ip = interpret_addr2(my_address->addr); + + if (my_ip.addr != 0 || my_address->port != 0) { + struct sockaddr_in my_addr; + ZERO_STRUCT(my_addr); +#ifdef HAVE_SOCK_SIN_LEN + my_addr.sin_len = sizeof(my_addr); +#endif + my_addr.sin_addr.s_addr = my_ip.addr; + my_addr.sin_port = htons(my_address->port); + my_addr.sin_family = PF_INET; + + ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + } + } + + if (srv_address->sockaddr) { + ret = connect(sock->fd, srv_address->sockaddr, srv_address->sockaddrlen); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + } else { + srv_ip = interpret_addr2(srv_address->addr); + if (!srv_ip.addr) { + return NT_STATUS_BAD_NETWORK_NAME; + } + + ZERO_STRUCT(srv_addr); +#ifdef HAVE_SOCK_SIN_LEN + srv_addr.sin_len = sizeof(srv_addr); +#endif + srv_addr.sin_addr.s_addr= srv_ip.addr; + srv_addr.sin_port = htons(srv_address->port); + srv_addr.sin_family = PF_INET; + + ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr)); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + } + + return ip_connect_complete(sock, flags); +} + + +/* + note that for simplicity of the API, socket_listen() is also + use for DGRAM sockets, but in reality only a bind() is done +*/ +static NTSTATUS ipv4_listen(struct socket_context *sock, + const struct socket_address *my_address, + int queue_size, uint32_t flags) +{ + struct sockaddr_in my_addr; + struct ipv4_addr ip_addr; + int ret; + + socket_set_option(sock, "SO_REUSEADDR=1", NULL); + + if (my_address->sockaddr) { + ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); + } else { + ip_addr = interpret_addr2(my_address->addr); + + ZERO_STRUCT(my_addr); +#ifdef HAVE_SOCK_SIN_LEN + my_addr.sin_len = sizeof(my_addr); +#endif + my_addr.sin_addr.s_addr = ip_addr.addr; + my_addr.sin_port = htons(my_address->port); + my_addr.sin_family = PF_INET; + + ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); + } + + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + if (sock->type == SOCKET_TYPE_STREAM) { + ret = listen(sock->fd, queue_size); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + } + + if (!(flags & SOCKET_FLAG_BLOCK)) { + ret = set_blocking(sock->fd, false); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + } + + sock->state= SOCKET_STATE_SERVER_LISTEN; + + return NT_STATUS_OK; +} + +static NTSTATUS ipv4_accept(struct socket_context *sock, struct socket_context **new_sock) +{ + struct sockaddr_in cli_addr; + socklen_t cli_addr_len = sizeof(cli_addr); + int new_fd; + + if (sock->type != SOCKET_TYPE_STREAM) { + return NT_STATUS_INVALID_PARAMETER; + } + + new_fd = accept(sock->fd, (struct sockaddr *)&cli_addr, &cli_addr_len); + if (new_fd == -1) { + return map_nt_error_from_unix(errno); + } + + if (!(sock->flags & SOCKET_FLAG_BLOCK)) { + int ret = set_blocking(new_fd, false); + if (ret == -1) { + close(new_fd); + return map_nt_error_from_unix(errno); + } + } + + /* TODO: we could add a 'accept_check' hook here + * which get the black/white lists via socket_set_accept_filter() + * or something like that + * --metze + */ + + (*new_sock) = talloc(NULL, struct socket_context); + if (!(*new_sock)) { + close(new_fd); + return NT_STATUS_NO_MEMORY; + } + + /* copy the socket_context */ + (*new_sock)->type = sock->type; + (*new_sock)->state = SOCKET_STATE_SERVER_CONNECTED; + (*new_sock)->flags = sock->flags; + + (*new_sock)->fd = new_fd; + + (*new_sock)->private_data = NULL; + (*new_sock)->ops = sock->ops; + (*new_sock)->backend_name = sock->backend_name; + + return NT_STATUS_OK; +} + +static NTSTATUS ip_recv(struct socket_context *sock, void *buf, + size_t wantlen, size_t *nread) +{ + ssize_t gotlen; + + *nread = 0; + + gotlen = recv(sock->fd, buf, wantlen, 0); + if (gotlen == 0) { + return NT_STATUS_END_OF_FILE; + } else if (gotlen == -1) { + return map_nt_error_from_unix(errno); + } + + *nread = gotlen; + + return NT_STATUS_OK; +} + + +static NTSTATUS ipv4_recvfrom(struct socket_context *sock, void *buf, + size_t wantlen, size_t *nread, + TALLOC_CTX *addr_ctx, struct socket_address **_src) +{ + ssize_t gotlen; + struct sockaddr_in *from_addr; + socklen_t from_len = sizeof(*from_addr); + struct socket_address *src; + char addrstring[INET_ADDRSTRLEN]; + + src = talloc(addr_ctx, struct socket_address); + if (!src) { + return NT_STATUS_NO_MEMORY; + } + + src->family = sock->backend_name; + + from_addr = talloc(src, struct sockaddr_in); + if (!from_addr) { + talloc_free(src); + return NT_STATUS_NO_MEMORY; + } + + src->sockaddr = (struct sockaddr *)from_addr; + + *nread = 0; + + gotlen = recvfrom(sock->fd, buf, wantlen, 0, + src->sockaddr, &from_len); + if (gotlen == 0) { + talloc_free(src); + return NT_STATUS_END_OF_FILE; + } else if (gotlen == -1) { + talloc_free(src); + return map_nt_error_from_unix(errno); + } + + src->sockaddrlen = from_len; + + if (inet_ntop(AF_INET, &from_addr->sin_addr, addrstring, + sizeof(addrstring)) == NULL) { + talloc_free(src); + return NT_STATUS_INTERNAL_ERROR; + } + src->addr = talloc_strdup(src, addrstring); + if (src->addr == NULL) { + talloc_free(src); + return NT_STATUS_NO_MEMORY; + } + src->port = ntohs(from_addr->sin_port); + + *nread = gotlen; + *_src = src; + return NT_STATUS_OK; +} + +static NTSTATUS ip_send(struct socket_context *sock, + const DATA_BLOB *blob, size_t *sendlen) +{ + ssize_t len; + + *sendlen = 0; + + len = send(sock->fd, blob->data, blob->length, 0); + if (len == -1) { + return map_nt_error_from_unix(errno); + } + + *sendlen = len; + + return NT_STATUS_OK; +} + +static NTSTATUS ipv4_sendto(struct socket_context *sock, + const DATA_BLOB *blob, size_t *sendlen, + const struct socket_address *dest_addr) +{ + ssize_t len; + + if (dest_addr->sockaddr) { + len = sendto(sock->fd, blob->data, blob->length, 0, + dest_addr->sockaddr, dest_addr->sockaddrlen); + } else { + struct sockaddr_in srv_addr; + struct ipv4_addr addr; + + ZERO_STRUCT(srv_addr); +#ifdef HAVE_SOCK_SIN_LEN + srv_addr.sin_len = sizeof(srv_addr); +#endif + addr = interpret_addr2(dest_addr->addr); + if (addr.addr == 0) { + return NT_STATUS_HOST_UNREACHABLE; + } + srv_addr.sin_addr.s_addr = addr.addr; + srv_addr.sin_port = htons(dest_addr->port); + srv_addr.sin_family = PF_INET; + + *sendlen = 0; + + len = sendto(sock->fd, blob->data, blob->length, 0, + (struct sockaddr *)&srv_addr, sizeof(srv_addr)); + } + if (len == -1) { + return map_nt_error_from_unix(errno); + } + + *sendlen = len; + + return NT_STATUS_OK; +} + +static NTSTATUS ipv4_set_option(struct socket_context *sock, const char *option, const char *val) +{ + set_socket_options(sock->fd, option); + return NT_STATUS_OK; +} + +static char *ipv4_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx) +{ + struct sockaddr_in peer_addr; + socklen_t len = sizeof(peer_addr); + struct hostent *he; + int ret; + + ret = getpeername(sock->fd, (struct sockaddr *)&peer_addr, &len); + if (ret == -1) { + return NULL; + } + + he = gethostbyaddr((char *)&peer_addr.sin_addr, sizeof(peer_addr.sin_addr), AF_INET); + if (he == NULL) { + return NULL; + } + + return talloc_strdup(mem_ctx, he->h_name); +} + +static struct socket_address *ipv4_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +{ + struct sockaddr_in *peer_addr; + socklen_t len = sizeof(*peer_addr); + struct socket_address *peer; + char addrstring[INET_ADDRSTRLEN]; + int ret; + + peer = talloc(mem_ctx, struct socket_address); + if (!peer) { + return NULL; + } + + peer->family = sock->backend_name; + peer_addr = talloc(peer, struct sockaddr_in); + if (!peer_addr) { + talloc_free(peer); + return NULL; + } + + peer->sockaddr = (struct sockaddr *)peer_addr; + + ret = getpeername(sock->fd, peer->sockaddr, &len); + if (ret == -1) { + talloc_free(peer); + return NULL; + } + + peer->sockaddrlen = len; + + if (inet_ntop(AF_INET, &peer_addr->sin_addr, addrstring, + sizeof(addrstring)) == NULL) { + talloc_free(peer); + return NULL; + } + peer->addr = talloc_strdup(peer, addrstring); + if (!peer->addr) { + talloc_free(peer); + return NULL; + } + peer->port = ntohs(peer_addr->sin_port); + + return peer; +} + +static struct socket_address *ipv4_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +{ + struct sockaddr_in *local_addr; + socklen_t len = sizeof(*local_addr); + struct socket_address *local; + char addrstring[INET_ADDRSTRLEN]; + int ret; + + local = talloc(mem_ctx, struct socket_address); + if (!local) { + return NULL; + } + + local->family = sock->backend_name; + local_addr = talloc(local, struct sockaddr_in); + if (!local_addr) { + talloc_free(local); + return NULL; + } + + local->sockaddr = (struct sockaddr *)local_addr; + + ret = getsockname(sock->fd, local->sockaddr, &len); + if (ret == -1) { + talloc_free(local); + return NULL; + } + + local->sockaddrlen = len; + + if (inet_ntop(AF_INET, &local_addr->sin_addr, addrstring, + sizeof(addrstring)) == NULL) { + talloc_free(local); + return NULL; + } + local->addr = talloc_strdup(local, addrstring); + if (!local->addr) { + talloc_free(local); + return NULL; + } + local->port = ntohs(local_addr->sin_port); + + return local; +} +static int ip_get_fd(struct socket_context *sock) +{ + return sock->fd; +} + +static NTSTATUS ip_pending(struct socket_context *sock, size_t *npending) +{ + int value = 0; + if (ioctl(sock->fd, FIONREAD, &value) == 0) { + *npending = value; + return NT_STATUS_OK; + } + return map_nt_error_from_unix(errno); +} + +static const struct socket_ops ipv4_ops = { + .name = "ipv4", + .fn_init = ipv4_init, + .fn_connect = ipv4_connect, + .fn_connect_complete = ip_connect_complete, + .fn_listen = ipv4_listen, + .fn_accept = ipv4_accept, + .fn_recv = ip_recv, + .fn_recvfrom = ipv4_recvfrom, + .fn_send = ip_send, + .fn_sendto = ipv4_sendto, + .fn_pending = ip_pending, + .fn_close = ip_close, + + .fn_set_option = ipv4_set_option, + + .fn_get_peer_name = ipv4_get_peer_name, + .fn_get_peer_addr = ipv4_get_peer_addr, + .fn_get_my_addr = ipv4_get_my_addr, + + .fn_get_fd = ip_get_fd +}; + +const struct socket_ops *socket_ipv4_ops(enum socket_type type) +{ + return &ipv4_ops; +} + +#if HAVE_IPV6 + +static struct in6_addr interpret_addr6(const char *name) +{ + struct hostent *he; + + if (name == NULL) return in6addr_any; + + if (strcasecmp(name, "localhost") == 0) { + name = "::1"; + } + + he = gethostbyname2(name, PF_INET6); + + if (he == NULL) return in6addr_any; + + return *((struct in6_addr *)he->h_addr); +} + +static NTSTATUS ipv6_init(struct socket_context *sock) +{ + int type; + + switch (sock->type) { + case SOCKET_TYPE_STREAM: + type = SOCK_STREAM; + break; + case SOCKET_TYPE_DGRAM: + type = SOCK_DGRAM; + break; + default: + return NT_STATUS_INVALID_PARAMETER; + } + + sock->fd = socket(PF_INET6, type, 0); + if (sock->fd == -1) { + return map_nt_error_from_unix(errno); + } + + sock->backend_name = "ipv6"; + sock->family = AF_INET6; + + return NT_STATUS_OK; +} + +static NTSTATUS ipv6_tcp_connect(struct socket_context *sock, + const struct socket_address *my_address, + const struct socket_address *srv_address, + uint32_t flags) +{ + int ret; + + if (my_address && my_address->sockaddr) { + ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + } else if (my_address) { + struct in6_addr my_ip; + my_ip = interpret_addr6(my_address->addr); + + if (memcmp(&my_ip, &in6addr_any, sizeof(my_ip)) || my_address->port != 0) { + struct sockaddr_in6 my_addr; + ZERO_STRUCT(my_addr); + my_addr.sin6_addr = my_ip; + my_addr.sin6_port = htons(my_address->port); + my_addr.sin6_family = PF_INET6; + + ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + } + } + + if (srv_address->sockaddr) { + ret = connect(sock->fd, srv_address->sockaddr, srv_address->sockaddrlen); + } else { + struct in6_addr srv_ip; + struct sockaddr_in6 srv_addr; + srv_ip = interpret_addr6(srv_address->addr); + if (memcmp(&srv_ip, &in6addr_any, sizeof(srv_ip)) == 0) { + return NT_STATUS_BAD_NETWORK_NAME; + } + + ZERO_STRUCT(srv_addr); + srv_addr.sin6_addr = srv_ip; + srv_addr.sin6_port = htons(srv_address->port); + srv_addr.sin6_family = PF_INET6; + + ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr)); + } + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + return ip_connect_complete(sock, flags); +} + +static NTSTATUS ipv6_listen(struct socket_context *sock, + const struct socket_address *my_address, + int queue_size, uint32_t flags) +{ + struct sockaddr_in6 my_addr; + struct in6_addr ip_addr; + int ret; + + socket_set_option(sock, "SO_REUSEADDR=1", NULL); + + if (my_address->sockaddr) { + ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); + } else { + ip_addr = interpret_addr6(my_address->addr); + + ZERO_STRUCT(my_addr); + my_addr.sin6_addr = ip_addr; + my_addr.sin6_port = htons(my_address->port); + my_addr.sin6_family = PF_INET6; + + ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); + } + + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + + if (sock->type == SOCKET_TYPE_STREAM) { + ret = listen(sock->fd, queue_size); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + } + + if (!(flags & SOCKET_FLAG_BLOCK)) { + ret = set_blocking(sock->fd, false); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + } + + sock->state= SOCKET_STATE_SERVER_LISTEN; + + return NT_STATUS_OK; +} + +static NTSTATUS ipv6_tcp_accept(struct socket_context *sock, struct socket_context **new_sock) +{ + struct sockaddr_in cli_addr; + socklen_t cli_addr_len = sizeof(cli_addr); + int new_fd; + + if (sock->type != SOCKET_TYPE_STREAM) { + return NT_STATUS_INVALID_PARAMETER; + } + + new_fd = accept(sock->fd, (struct sockaddr *)&cli_addr, &cli_addr_len); + if (new_fd == -1) { + return map_nt_error_from_unix(errno); + } + + if (!(sock->flags & SOCKET_FLAG_BLOCK)) { + int ret = set_blocking(new_fd, false); + if (ret == -1) { + close(new_fd); + return map_nt_error_from_unix(errno); + } + } + + /* TODO: we could add a 'accept_check' hook here + * which get the black/white lists via socket_set_accept_filter() + * or something like that + * --metze + */ + + (*new_sock) = talloc(NULL, struct socket_context); + if (!(*new_sock)) { + close(new_fd); + return NT_STATUS_NO_MEMORY; + } + + /* copy the socket_context */ + (*new_sock)->type = sock->type; + (*new_sock)->state = SOCKET_STATE_SERVER_CONNECTED; + (*new_sock)->flags = sock->flags; + + (*new_sock)->fd = new_fd; + + (*new_sock)->private_data = NULL; + (*new_sock)->ops = sock->ops; + (*new_sock)->backend_name = sock->backend_name; + + return NT_STATUS_OK; +} + +static NTSTATUS ipv6_recvfrom(struct socket_context *sock, void *buf, + size_t wantlen, size_t *nread, + TALLOC_CTX *addr_ctx, struct socket_address **_src) +{ + ssize_t gotlen; + struct sockaddr_in6 *from_addr; + socklen_t from_len = sizeof(*from_addr); + struct socket_address *src; + char addrstring[INET6_ADDRSTRLEN]; + + src = talloc(addr_ctx, struct socket_address); + if (!src) { + return NT_STATUS_NO_MEMORY; + } + + src->family = sock->backend_name; + + from_addr = talloc(src, struct sockaddr_in6); + if (!from_addr) { + talloc_free(src); + return NT_STATUS_NO_MEMORY; + } + + src->sockaddr = (struct sockaddr *)from_addr; + + *nread = 0; + + gotlen = recvfrom(sock->fd, buf, wantlen, 0, + src->sockaddr, &from_len); + if (gotlen == 0) { + talloc_free(src); + return NT_STATUS_END_OF_FILE; + } else if (gotlen == -1) { + talloc_free(src); + return map_nt_error_from_unix(errno); + } + + src->sockaddrlen = from_len; + + if (inet_ntop(AF_INET6, &from_addr->sin6_addr, addrstring, sizeof(addrstring)) == NULL) { + DEBUG(0, ("Unable to convert address to string: %s\n", strerror(errno))); + talloc_free(src); + return NT_STATUS_INTERNAL_ERROR; + } + + src->addr = talloc_strdup(src, addrstring); + if (src->addr == NULL) { + talloc_free(src); + return NT_STATUS_NO_MEMORY; + } + src->port = ntohs(from_addr->sin6_port); + + *nread = gotlen; + *_src = src; + return NT_STATUS_OK; +} + +static NTSTATUS ipv6_sendto(struct socket_context *sock, + const DATA_BLOB *blob, size_t *sendlen, + const struct socket_address *dest_addr) +{ + ssize_t len; + + if (dest_addr->sockaddr) { + len = sendto(sock->fd, blob->data, blob->length, 0, + dest_addr->sockaddr, dest_addr->sockaddrlen); + } else { + struct sockaddr_in6 srv_addr; + struct in6_addr addr; + + ZERO_STRUCT(srv_addr); + addr = interpret_addr6(dest_addr->addr); + if (addr.s6_addr == 0) { + return NT_STATUS_HOST_UNREACHABLE; + } + srv_addr.sin6_addr = addr; + srv_addr.sin6_port = htons(dest_addr->port); + srv_addr.sin6_family = PF_INET6; + + *sendlen = 0; + + len = sendto(sock->fd, blob->data, blob->length, 0, + (struct sockaddr *)&srv_addr, sizeof(srv_addr)); + } + if (len == -1) { + return map_nt_error_from_unix(errno); + } + + *sendlen = len; + + return NT_STATUS_OK; +} + +static NTSTATUS ipv6_set_option(struct socket_context *sock, const char *option, const char *val) +{ + set_socket_options(sock->fd, option); + return NT_STATUS_OK; +} + +static char *ipv6_tcp_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx) +{ + struct sockaddr_in6 peer_addr; + socklen_t len = sizeof(peer_addr); + struct hostent *he; + int ret; + + ret = getpeername(sock->fd, (struct sockaddr *)&peer_addr, &len); + if (ret == -1) { + return NULL; + } + + he = gethostbyaddr((char *)&peer_addr.sin6_addr, sizeof(peer_addr.sin6_addr), AF_INET6); + if (he == NULL) { + return NULL; + } + + return talloc_strdup(mem_ctx, he->h_name); +} + +static struct socket_address *ipv6_tcp_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +{ + struct sockaddr_in6 *peer_addr; + socklen_t len = sizeof(*peer_addr); + struct socket_address *peer; + int ret; + char addr[128]; + const char *addr_ret; + + peer = talloc(mem_ctx, struct socket_address); + if (!peer) { + return NULL; + } + + peer->family = sock->backend_name; + peer_addr = talloc(peer, struct sockaddr_in6); + if (!peer_addr) { + talloc_free(peer); + return NULL; + } + + peer->sockaddr = (struct sockaddr *)peer_addr; + + ret = getpeername(sock->fd, peer->sockaddr, &len); + if (ret == -1) { + talloc_free(peer); + return NULL; + } + + peer->sockaddrlen = len; + + addr_ret = inet_ntop(AF_INET6, &peer_addr->sin6_addr, addr, sizeof(addr)); + if (addr_ret == NULL) { + talloc_free(peer); + return NULL; + } + + peer->addr = talloc_strdup(peer, addr_ret); + if (peer->addr == NULL) { + talloc_free(peer); + return NULL; + } + + peer->port = ntohs(peer_addr->sin6_port); + + return peer; +} + +static struct socket_address *ipv6_tcp_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +{ + struct sockaddr_in6 *local_addr; + socklen_t len = sizeof(*local_addr); + struct socket_address *local; + int ret; + char addrstring[INET6_ADDRSTRLEN]; + + local = talloc(mem_ctx, struct socket_address); + if (!local) { + return NULL; + } + + local->family = sock->backend_name; + local_addr = talloc(local, struct sockaddr_in6); + if (!local_addr) { + talloc_free(local); + return NULL; + } + + local->sockaddr = (struct sockaddr *)local_addr; + + ret = getsockname(sock->fd, local->sockaddr, &len); + if (ret == -1) { + talloc_free(local); + return NULL; + } + + local->sockaddrlen = len; + + if (inet_ntop(AF_INET6, &local_addr->sin6_addr, addrstring, + sizeof(addrstring)) == NULL) { + DEBUG(0, ("Unable to convert address to string: %s\n", + strerror(errno))); + talloc_free(local); + return NULL; + } + + local->addr = talloc_strdup(mem_ctx, addrstring); + if (!local->addr) { + talloc_free(local); + return NULL; + } + local->port = ntohs(local_addr->sin6_port); + + return local; +} + +static const struct socket_ops ipv6_tcp_ops = { + .name = "ipv6", + .fn_init = ipv6_init, + .fn_connect = ipv6_tcp_connect, + .fn_connect_complete = ip_connect_complete, + .fn_listen = ipv6_listen, + .fn_accept = ipv6_tcp_accept, + .fn_recv = ip_recv, + .fn_recvfrom = ipv6_recvfrom, + .fn_send = ip_send, + .fn_sendto = ipv6_sendto, + .fn_pending = ip_pending, + .fn_close = ip_close, + + .fn_set_option = ipv6_set_option, + + .fn_get_peer_name = ipv6_tcp_get_peer_name, + .fn_get_peer_addr = ipv6_tcp_get_peer_addr, + .fn_get_my_addr = ipv6_tcp_get_my_addr, + + .fn_get_fd = ip_get_fd +}; + +const struct socket_ops *socket_ipv6_ops(enum socket_type type) +{ + return &ipv6_tcp_ops; +} + +#endif diff --git a/source4/lib/socket/socket_ipv4.c b/source4/lib/socket/socket_ipv4.c deleted file mode 100644 index d9a4ff0bd1..0000000000 --- a/source4/lib/socket/socket_ipv4.c +++ /dev/null @@ -1,539 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - Socket IPv4 functions - - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Andrew Tridgell 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 - the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "system/filesys.h" -#include "lib/socket/socket.h" -#include "system/network.h" - -static NTSTATUS ipv4_init(struct socket_context *sock) -{ - int type; - - switch (sock->type) { - case SOCKET_TYPE_STREAM: - type = SOCK_STREAM; - break; - case SOCKET_TYPE_DGRAM: - type = SOCK_DGRAM; - break; - default: - return NT_STATUS_INVALID_PARAMETER; - } - - sock->fd = socket(PF_INET, type, 0); - if (sock->fd == -1) { - return map_nt_error_from_unix(errno); - } - - sock->backend_name = "ipv4"; - - return NT_STATUS_OK; -} - -static void ipv4_close(struct socket_context *sock) -{ - close(sock->fd); -} - -static NTSTATUS ipv4_connect_complete(struct socket_context *sock, uint32_t flags) -{ - int error=0, ret; - socklen_t len = sizeof(error); - - /* check for any errors that may have occurred - this is needed - for non-blocking connect */ - ret = getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, &error, &len); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - if (error != 0) { - return map_nt_error_from_unix(error); - } - - if (!(flags & SOCKET_FLAG_BLOCK)) { - ret = set_blocking(sock->fd, False); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - } - - sock->state = SOCKET_STATE_CLIENT_CONNECTED; - - return NT_STATUS_OK; -} - - -static NTSTATUS ipv4_connect(struct socket_context *sock, - const struct socket_address *my_address, - const struct socket_address *srv_address, - uint32_t flags) -{ - struct sockaddr_in srv_addr; - struct ipv4_addr my_ip; - struct ipv4_addr srv_ip; - int ret; - - if (my_address && my_address->sockaddr) { - ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - } else if (my_address) { - my_ip = interpret_addr2(my_address->addr); - - if (my_ip.addr != 0 || my_address->port != 0) { - struct sockaddr_in my_addr; - ZERO_STRUCT(my_addr); -#ifdef HAVE_SOCK_SIN_LEN - my_addr.sin_len = sizeof(my_addr); -#endif - my_addr.sin_addr.s_addr = my_ip.addr; - my_addr.sin_port = htons(my_address->port); - my_addr.sin_family = PF_INET; - - ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - } - } - - if (srv_address->sockaddr) { - ret = connect(sock->fd, srv_address->sockaddr, srv_address->sockaddrlen); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - } else { - srv_ip = interpret_addr2(srv_address->addr); - if (!srv_ip.addr) { - return NT_STATUS_BAD_NETWORK_NAME; - } - - ZERO_STRUCT(srv_addr); -#ifdef HAVE_SOCK_SIN_LEN - srv_addr.sin_len = sizeof(srv_addr); -#endif - srv_addr.sin_addr.s_addr= srv_ip.addr; - srv_addr.sin_port = htons(srv_address->port); - srv_addr.sin_family = PF_INET; - - ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr)); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - } - - return ipv4_connect_complete(sock, flags); -} - - -/* - note that for simplicity of the API, socket_listen() is also - use for DGRAM sockets, but in reality only a bind() is done -*/ -static NTSTATUS ipv4_listen(struct socket_context *sock, - const struct socket_address *my_address, - int queue_size, uint32_t flags) -{ - struct sockaddr_in my_addr; - struct ipv4_addr ip_addr; - int ret; - - socket_set_option(sock, "SO_REUSEADDR=1", NULL); - - if (my_address->sockaddr) { - ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); - } else { - ip_addr = interpret_addr2(my_address->addr); - - ZERO_STRUCT(my_addr); -#ifdef HAVE_SOCK_SIN_LEN - my_addr.sin_len = sizeof(my_addr); -#endif - my_addr.sin_addr.s_addr = ip_addr.addr; - my_addr.sin_port = htons(my_address->port); - my_addr.sin_family = PF_INET; - - ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); - } - - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - - if (sock->type == SOCKET_TYPE_STREAM) { - ret = listen(sock->fd, queue_size); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - } - - if (!(flags & SOCKET_FLAG_BLOCK)) { - ret = set_blocking(sock->fd, False); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - } - - sock->state= SOCKET_STATE_SERVER_LISTEN; - - return NT_STATUS_OK; -} - -static NTSTATUS ipv4_accept(struct socket_context *sock, struct socket_context **new_sock) -{ - struct sockaddr_in cli_addr; - socklen_t cli_addr_len = sizeof(cli_addr); - int new_fd; - - if (sock->type != SOCKET_TYPE_STREAM) { - return NT_STATUS_INVALID_PARAMETER; - } - - new_fd = accept(sock->fd, (struct sockaddr *)&cli_addr, &cli_addr_len); - if (new_fd == -1) { - return map_nt_error_from_unix(errno); - } - - if (!(sock->flags & SOCKET_FLAG_BLOCK)) { - int ret = set_blocking(new_fd, False); - if (ret == -1) { - close(new_fd); - return map_nt_error_from_unix(errno); - } - } - - /* TODO: we could add a 'accept_check' hook here - * which get the black/white lists via socket_set_accept_filter() - * or something like that - * --metze - */ - - (*new_sock) = talloc(NULL, struct socket_context); - if (!(*new_sock)) { - close(new_fd); - return NT_STATUS_NO_MEMORY; - } - - /* copy the socket_context */ - (*new_sock)->type = sock->type; - (*new_sock)->state = SOCKET_STATE_SERVER_CONNECTED; - (*new_sock)->flags = sock->flags; - - (*new_sock)->fd = new_fd; - - (*new_sock)->private_data = NULL; - (*new_sock)->ops = sock->ops; - (*new_sock)->backend_name = sock->backend_name; - - return NT_STATUS_OK; -} - -static NTSTATUS ipv4_recv(struct socket_context *sock, void *buf, - size_t wantlen, size_t *nread) -{ - ssize_t gotlen; - - *nread = 0; - - gotlen = recv(sock->fd, buf, wantlen, 0); - if (gotlen == 0) { - return NT_STATUS_END_OF_FILE; - } else if (gotlen == -1) { - return map_nt_error_from_unix(errno); - } - - *nread = gotlen; - - return NT_STATUS_OK; -} - - -static NTSTATUS ipv4_recvfrom(struct socket_context *sock, void *buf, - size_t wantlen, size_t *nread, - TALLOC_CTX *addr_ctx, struct socket_address **_src) -{ - ssize_t gotlen; - struct sockaddr_in *from_addr; - socklen_t from_len = sizeof(*from_addr); - struct socket_address *src; - const char *addr; - - src = talloc(addr_ctx, struct socket_address); - if (!src) { - return NT_STATUS_NO_MEMORY; - } - - src->family = sock->backend_name; - - from_addr = talloc(src, struct sockaddr_in); - if (!from_addr) { - talloc_free(src); - return NT_STATUS_NO_MEMORY; - } - - src->sockaddr = (struct sockaddr *)from_addr; - - *nread = 0; - - gotlen = recvfrom(sock->fd, buf, wantlen, 0, - src->sockaddr, &from_len); - if (gotlen == 0) { - talloc_free(src); - return NT_STATUS_END_OF_FILE; - } else if (gotlen == -1) { - talloc_free(src); - return map_nt_error_from_unix(errno); - } - - src->sockaddrlen = from_len; - - addr = inet_ntoa(from_addr->sin_addr); - if (addr == NULL) { - talloc_free(src); - return NT_STATUS_INTERNAL_ERROR; - } - src->addr = talloc_strdup(src, addr); - if (src->addr == NULL) { - talloc_free(src); - return NT_STATUS_NO_MEMORY; - } - src->port = ntohs(from_addr->sin_port); - - *nread = gotlen; - *_src = src; - return NT_STATUS_OK; -} - -static NTSTATUS ipv4_send(struct socket_context *sock, - const DATA_BLOB *blob, size_t *sendlen) -{ - ssize_t len; - - *sendlen = 0; - - len = send(sock->fd, blob->data, blob->length, 0); - if (len == -1) { - return map_nt_error_from_unix(errno); - } - - *sendlen = len; - - return NT_STATUS_OK; -} - -static NTSTATUS ipv4_sendto(struct socket_context *sock, - const DATA_BLOB *blob, size_t *sendlen, - const struct socket_address *dest_addr) -{ - ssize_t len; - - if (dest_addr->sockaddr) { - len = sendto(sock->fd, blob->data, blob->length, 0, - dest_addr->sockaddr, dest_addr->sockaddrlen); - } else { - struct sockaddr_in srv_addr; - struct ipv4_addr addr; - - ZERO_STRUCT(srv_addr); -#ifdef HAVE_SOCK_SIN_LEN - srv_addr.sin_len = sizeof(srv_addr); -#endif - addr = interpret_addr2(dest_addr->addr); - if (addr.addr == 0) { - return NT_STATUS_HOST_UNREACHABLE; - } - srv_addr.sin_addr.s_addr = addr.addr; - srv_addr.sin_port = htons(dest_addr->port); - srv_addr.sin_family = PF_INET; - - *sendlen = 0; - - len = sendto(sock->fd, blob->data, blob->length, 0, - (struct sockaddr *)&srv_addr, sizeof(srv_addr)); - } - if (len == -1) { - return map_nt_error_from_unix(errno); - } - - *sendlen = len; - - return NT_STATUS_OK; -} - -static NTSTATUS ipv4_set_option(struct socket_context *sock, const char *option, const char *val) -{ - set_socket_options(sock->fd, option); - return NT_STATUS_OK; -} - -static char *ipv4_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx) -{ - struct sockaddr_in peer_addr; - socklen_t len = sizeof(peer_addr); - struct hostent *he; - int ret; - - ret = getpeername(sock->fd, (struct sockaddr *)&peer_addr, &len); - if (ret == -1) { - return NULL; - } - - he = gethostbyaddr((char *)&peer_addr.sin_addr, sizeof(peer_addr.sin_addr), AF_INET); - if (he == NULL) { - return NULL; - } - - return talloc_strdup(mem_ctx, he->h_name); -} - -static struct socket_address *ipv4_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) -{ - struct sockaddr_in *peer_addr; - socklen_t len = sizeof(*peer_addr); - const char *addr; - struct socket_address *peer; - int ret; - - peer = talloc(mem_ctx, struct socket_address); - if (!peer) { - return NULL; - } - - peer->family = sock->backend_name; - peer_addr = talloc(peer, struct sockaddr_in); - if (!peer_addr) { - talloc_free(peer); - return NULL; - } - - peer->sockaddr = (struct sockaddr *)peer_addr; - - ret = getpeername(sock->fd, peer->sockaddr, &len); - if (ret == -1) { - talloc_free(peer); - return NULL; - } - - peer->sockaddrlen = len; - - addr = inet_ntoa(peer_addr->sin_addr); - if (addr == NULL) { - talloc_free(peer); - return NULL; - } - peer->addr = talloc_strdup(peer, addr); - if (!peer->addr) { - talloc_free(peer); - return NULL; - } - peer->port = ntohs(peer_addr->sin_port); - - return peer; -} - -static struct socket_address *ipv4_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) -{ - struct sockaddr_in *local_addr; - socklen_t len = sizeof(*local_addr); - const char *addr; - struct socket_address *local; - int ret; - - local = talloc(mem_ctx, struct socket_address); - if (!local) { - return NULL; - } - - local->family = sock->backend_name; - local_addr = talloc(local, struct sockaddr_in); - if (!local_addr) { - talloc_free(local); - return NULL; - } - - local->sockaddr = (struct sockaddr *)local_addr; - - ret = getsockname(sock->fd, local->sockaddr, &len); - if (ret == -1) { - talloc_free(local); - return NULL; - } - - local->sockaddrlen = len; - - addr = inet_ntoa(local_addr->sin_addr); - if (addr == NULL) { - talloc_free(local); - return NULL; - } - local->addr = talloc_strdup(local, addr); - if (!local->addr) { - talloc_free(local); - return NULL; - } - local->port = ntohs(local_addr->sin_port); - - return local; -} -static int ipv4_get_fd(struct socket_context *sock) -{ - return sock->fd; -} - -static NTSTATUS ipv4_pending(struct socket_context *sock, size_t *npending) -{ - int value = 0; - if (ioctl(sock->fd, FIONREAD, &value) == 0) { - *npending = value; - return NT_STATUS_OK; - } - return map_nt_error_from_unix(errno); -} - -static const struct socket_ops ipv4_ops = { - .name = "ipv4", - .fn_init = ipv4_init, - .fn_connect = ipv4_connect, - .fn_connect_complete = ipv4_connect_complete, - .fn_listen = ipv4_listen, - .fn_accept = ipv4_accept, - .fn_recv = ipv4_recv, - .fn_recvfrom = ipv4_recvfrom, - .fn_send = ipv4_send, - .fn_sendto = ipv4_sendto, - .fn_pending = ipv4_pending, - .fn_close = ipv4_close, - - .fn_set_option = ipv4_set_option, - - .fn_get_peer_name = ipv4_get_peer_name, - .fn_get_peer_addr = ipv4_get_peer_addr, - .fn_get_my_addr = ipv4_get_my_addr, - .fn_get_fd = ipv4_get_fd -}; - -const struct socket_ops *socket_ipv4_ops(enum socket_type type) -{ - return &ipv4_ops; -} diff --git a/source4/lib/socket/socket_ipv6.c b/source4/lib/socket/socket_ipv6.c deleted file mode 100644 index 8b86958417..0000000000 --- a/source4/lib/socket/socket_ipv6.c +++ /dev/null @@ -1,527 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Socket IPv6 functions - Copyright (C) Stefan Metzmacher 2004 - Copyright (C) Jelmer Vernooij 2004 - - 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 3 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, see <http://www.gnu.org/licenses/>. -*/ - -#include "includes.h" -#include "lib/socket/socket.h" -#include "system/filesys.h" /* needed for close() */ -#include "system/network.h" - -static struct in6_addr interpret_addr6(const char *name) -{ - struct hostent *he; - - if (name == NULL) return in6addr_any; - - if (strcasecmp(name, "localhost") == 0) { - name = "::1"; - } - - he = gethostbyname2(name, PF_INET6); - - if (he == NULL) return in6addr_any; - - return *((struct in6_addr *)he->h_addr); -} - -static NTSTATUS ipv6_tcp_init(struct socket_context *sock) -{ - sock->fd = socket(PF_INET6, SOCK_STREAM, 0); - if (sock->fd == -1) { - return map_nt_error_from_unix(errno); - } - - sock->backend_name = "ipv6"; - - return NT_STATUS_OK; -} - -static void ipv6_tcp_close(struct socket_context *sock) -{ - close(sock->fd); -} - -static NTSTATUS ipv6_tcp_connect_complete(struct socket_context *sock, uint32_t flags) -{ - int error=0, ret; - socklen_t len = sizeof(error); - - /* check for any errors that may have occurred - this is needed - for non-blocking connect */ - ret = getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, &error, &len); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - if (error != 0) { - return map_nt_error_from_unix(error); - } - - if (!(flags & SOCKET_FLAG_BLOCK)) { - ret = set_blocking(sock->fd, False); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - } - - sock->state = SOCKET_STATE_CLIENT_CONNECTED; - - return NT_STATUS_OK; -} - -static NTSTATUS ipv6_tcp_connect(struct socket_context *sock, - const struct socket_address *my_address, - const struct socket_address *srv_address, - uint32_t flags) -{ - int ret; - - if (my_address && my_address->sockaddr) { - ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - } else if (my_address) { - struct in6_addr my_ip; - my_ip = interpret_addr6(my_address->addr); - - if (memcmp(&my_ip, &in6addr_any, sizeof(my_ip)) || my_address->port != 0) { - struct sockaddr_in6 my_addr; - ZERO_STRUCT(my_addr); - my_addr.sin6_addr = my_ip; - my_addr.sin6_port = htons(my_address->port); - my_addr.sin6_family = PF_INET6; - - ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - } - } - - if (srv_address->sockaddr) { - ret = connect(sock->fd, srv_address->sockaddr, srv_address->sockaddrlen); - } else { - struct in6_addr srv_ip; - struct sockaddr_in6 srv_addr; - srv_ip = interpret_addr6(srv_address->addr); - if (memcmp(&srv_ip, &in6addr_any, sizeof(srv_ip)) == 0) { - return NT_STATUS_BAD_NETWORK_NAME; - } - - ZERO_STRUCT(srv_addr); - srv_addr.sin6_addr = srv_ip; - srv_addr.sin6_port = htons(srv_address->port); - srv_addr.sin6_family = PF_INET6; - - ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr)); - } - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - - return ipv6_tcp_connect_complete(sock, flags); -} - -static NTSTATUS ipv6_tcp_listen(struct socket_context *sock, - const struct socket_address *my_address, - int queue_size, uint32_t flags) -{ - struct sockaddr_in6 my_addr; - struct in6_addr ip_addr; - int ret; - - socket_set_option(sock, "SO_REUSEADDR=1", NULL); - - if (my_address->sockaddr) { - ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); - } else { - ip_addr = interpret_addr6(my_address->addr); - - ZERO_STRUCT(my_addr); - my_addr.sin6_addr = ip_addr; - my_addr.sin6_port = htons(my_address->port); - my_addr.sin6_family = PF_INET6; - - ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); - } - - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - - if (sock->type == SOCKET_TYPE_STREAM) { - ret = listen(sock->fd, queue_size); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - } - - if (!(flags & SOCKET_FLAG_BLOCK)) { - ret = set_blocking(sock->fd, False); - if (ret == -1) { - return map_nt_error_from_unix(errno); - } - } - - sock->state= SOCKET_STATE_SERVER_LISTEN; - - return NT_STATUS_OK; -} - -static NTSTATUS ipv6_tcp_accept(struct socket_context *sock, struct socket_context **new_sock) -{ - struct sockaddr_in cli_addr; - socklen_t cli_addr_len = sizeof(cli_addr); - int new_fd; - - if (sock->type != SOCKET_TYPE_STREAM) { - return NT_STATUS_INVALID_PARAMETER; - } - - - new_fd = accept(sock->fd, (struct sockaddr *)&cli_addr, &cli_addr_len); - if (new_fd == -1) { - return map_nt_error_from_unix(errno); - } - - if (!(sock->flags & SOCKET_FLAG_BLOCK)) { - int ret = set_blocking(new_fd, False); - if (ret == -1) { - close(new_fd); - return map_nt_error_from_unix(errno); - } - } - - /* TODO: we could add a 'accept_check' hook here - * which get the black/white lists via socket_set_accept_filter() - * or something like that - * --metze - */ - - (*new_sock) = talloc(NULL, struct socket_context); - if (!(*new_sock)) { - close(new_fd); - return NT_STATUS_NO_MEMORY; - } - - /* copy the socket_context */ - (*new_sock)->type = sock->type; - (*new_sock)->state = SOCKET_STATE_SERVER_CONNECTED; - (*new_sock)->flags = sock->flags; - - (*new_sock)->fd = new_fd; - - (*new_sock)->private_data = NULL; - (*new_sock)->ops = sock->ops; - (*new_sock)->backend_name = sock->backend_name; - - return NT_STATUS_OK; -} - -static NTSTATUS ipv6_tcp_recv(struct socket_context *sock, void *buf, - size_t wantlen, size_t *nread) -{ - ssize_t gotlen; - - *nread = 0; - - gotlen = recv(sock->fd, buf, wantlen, 0); - if (gotlen == 0) { - return NT_STATUS_END_OF_FILE; - } else if (gotlen == -1) { - return map_nt_error_from_unix(errno); - } - - *nread = gotlen; - - return NT_STATUS_OK; -} - -static NTSTATUS ipv6_recvfrom(struct socket_context *sock, void *buf, - size_t wantlen, size_t *nread, - TALLOC_CTX *addr_ctx, struct socket_address **_src) -{ - ssize_t gotlen; - struct sockaddr_in6 *from_addr; - socklen_t from_len = sizeof(*from_addr); - struct socket_address *src; - struct hostent *he; - - src = talloc(addr_ctx, struct socket_address); - if (!src) { - return NT_STATUS_NO_MEMORY; - } - - src->family = sock->backend_name; - - from_addr = talloc(src, struct sockaddr_in6); - if (!from_addr) { - talloc_free(src); - return NT_STATUS_NO_MEMORY; - } - - src->sockaddr = (struct sockaddr *)from_addr; - - *nread = 0; - - gotlen = recvfrom(sock->fd, buf, wantlen, 0, - src->sockaddr, &from_len); - if (gotlen == 0) { - talloc_free(src); - return NT_STATUS_END_OF_FILE; - } else if (gotlen == -1) { - talloc_free(src); - return map_nt_error_from_unix(errno); - } - - src->sockaddrlen = from_len; - - he = gethostbyaddr((void *)&from_addr->sin6_addr, sizeof(from_addr->sin6_addr), AF_INET6); - if (he == NULL) { - talloc_free(src); - return NT_STATUS_INTERNAL_ERROR; - } - src->addr = talloc_strdup(src, he->h_name); - if (src->addr == NULL) { - talloc_free(src); - return NT_STATUS_NO_MEMORY; - } - src->port = ntohs(from_addr->sin6_port); - - *nread = gotlen; - *_src = src; - return NT_STATUS_OK; -} - -static NTSTATUS ipv6_tcp_send(struct socket_context *sock, - const DATA_BLOB *blob, size_t *sendlen) -{ - ssize_t len; - - *sendlen = 0; - - len = send(sock->fd, blob->data, blob->length, 0); - if (len == -1) { - return map_nt_error_from_unix(errno); - } - - *sendlen = len; - - return NT_STATUS_OK; -} - -static NTSTATUS ipv6_sendto(struct socket_context *sock, - const DATA_BLOB *blob, size_t *sendlen, - const struct socket_address *dest_addr) -{ - ssize_t len; - - if (dest_addr->sockaddr) { - len = sendto(sock->fd, blob->data, blob->length, 0, - dest_addr->sockaddr, dest_addr->sockaddrlen); - } else { - struct sockaddr_in6 srv_addr; - struct in6_addr addr; - - ZERO_STRUCT(srv_addr); - addr = interpret_addr6(dest_addr->addr); - if (addr.s6_addr == 0) { - return NT_STATUS_HOST_UNREACHABLE; - } - srv_addr.sin6_addr = addr; - srv_addr.sin6_port = htons(dest_addr->port); - srv_addr.sin6_family = PF_INET6; - - *sendlen = 0; - - len = sendto(sock->fd, blob->data, blob->length, 0, - (struct sockaddr *)&srv_addr, sizeof(srv_addr)); - } - if (len == -1) { - return map_nt_error_from_unix(errno); - } - - *sendlen = len; - - return NT_STATUS_OK; -} - -static NTSTATUS ipv6_tcp_set_option(struct socket_context *sock, const char *option, const char *val) -{ - set_socket_options(sock->fd, option); - return NT_STATUS_OK; -} - -static char *ipv6_tcp_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx) -{ - struct sockaddr_in6 peer_addr; - socklen_t len = sizeof(peer_addr); - struct hostent *he; - int ret; - - ret = getpeername(sock->fd, (struct sockaddr *)&peer_addr, &len); - if (ret == -1) { - return NULL; - } - - he = gethostbyaddr((char *)&peer_addr.sin6_addr, sizeof(peer_addr.sin6_addr), AF_INET6); - if (he == NULL) { - return NULL; - } - - return talloc_strdup(mem_ctx, he->h_name); -} - -static struct socket_address *ipv6_tcp_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) -{ - struct sockaddr_in6 *peer_addr; - socklen_t len = sizeof(*peer_addr); - struct socket_address *peer; - int ret; - char addr[128]; - const char *addr_ret; - - peer = talloc(mem_ctx, struct socket_address); - if (!peer) { - return NULL; - } - - peer->family = sock->backend_name; - peer_addr = talloc(peer, struct sockaddr_in6); - if (!peer_addr) { - talloc_free(peer); - return NULL; - } - - peer->sockaddr = (struct sockaddr *)peer_addr; - - ret = getpeername(sock->fd, peer->sockaddr, &len); - if (ret == -1) { - talloc_free(peer); - return NULL; - } - - peer->sockaddrlen = len; - - addr_ret = inet_ntop(AF_INET6, &peer_addr->sin6_addr, addr, sizeof(addr)); - if (addr_ret == NULL) { - talloc_free(peer); - return NULL; - } - - peer->addr = talloc_strdup(peer, addr_ret); - if (peer->addr == NULL) { - talloc_free(peer); - return NULL; - } - - peer->port = ntohs(peer_addr->sin6_port); - - return peer; -} - -static struct socket_address *ipv6_tcp_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) -{ - struct sockaddr_in6 *local_addr; - socklen_t len = sizeof(*local_addr); - struct socket_address *local; - int ret; - struct hostent *he; - - local = talloc(mem_ctx, struct socket_address); - if (!local) { - return NULL; - } - - local->family = sock->backend_name; - local_addr = talloc(local, struct sockaddr_in6); - if (!local_addr) { - talloc_free(local); - return NULL; - } - - local->sockaddr = (struct sockaddr *)local_addr; - - ret = getsockname(sock->fd, local->sockaddr, &len); - if (ret == -1) { - talloc_free(local); - return NULL; - } - - local->sockaddrlen = len; - - he = gethostbyaddr((char *)&local_addr->sin6_addr, len, AF_INET6); - - if (!he || !he->h_name) { - talloc_free(local); - return NULL; - } - - local->addr = talloc_strdup(mem_ctx, he->h_name); - if (!local->addr) { - talloc_free(local); - return NULL; - } - local->port = ntohs(local_addr->sin6_port); - - return local; -} - -static int ipv6_tcp_get_fd(struct socket_context *sock) -{ - return sock->fd; -} - -static NTSTATUS ipv6_pending(struct socket_context *sock, size_t *npending) -{ - int value = 0; - if (ioctl(sock->fd, FIONREAD, &value) == 0) { - *npending = value; - return NT_STATUS_OK; - } - return map_nt_error_from_unix(errno); -} - -static const struct socket_ops ipv6_tcp_ops = { - .name = "ipv6", - .fn_init = ipv6_tcp_init, - .fn_connect = ipv6_tcp_connect, - .fn_connect_complete = ipv6_tcp_connect_complete, - .fn_listen = ipv6_tcp_listen, - .fn_accept = ipv6_tcp_accept, - .fn_recv = ipv6_tcp_recv, - .fn_recvfrom = ipv6_recvfrom, - .fn_sendto = ipv6_sendto, - .fn_send = ipv6_tcp_send, - .fn_close = ipv6_tcp_close, - .fn_pending = ipv6_pending, - - .fn_set_option = ipv6_tcp_set_option, - - .fn_get_peer_name = ipv6_tcp_get_peer_name, - .fn_get_peer_addr = ipv6_tcp_get_peer_addr, - .fn_get_my_addr = ipv6_tcp_get_my_addr, - - .fn_get_fd = ipv6_tcp_get_fd -}; - -const struct socket_ops *socket_ipv6_ops(enum socket_type type) -{ - return &ipv6_tcp_ops; -} diff --git a/source4/lib/socket/socket_unix.c b/source4/lib/socket/socket_unix.c index 7686fea1d8..cac4b8e913 100644 --- a/source4/lib/socket/socket_unix.c +++ b/source4/lib/socket/socket_unix.c @@ -82,7 +82,7 @@ static NTSTATUS unixdom_connect_complete(struct socket_context *sock, uint32_t f } if (!(flags & SOCKET_FLAG_BLOCK)) { - ret = set_blocking(sock->fd, False); + ret = set_blocking(sock->fd, false); if (ret == -1) { return map_nt_error_from_unix(errno); } @@ -161,7 +161,7 @@ static NTSTATUS unixdom_listen(struct socket_context *sock, } if (!(flags & SOCKET_FLAG_BLOCK)) { - ret = set_blocking(sock->fd, False); + ret = set_blocking(sock->fd, false); if (ret == -1) { return unixdom_error(errno); } @@ -190,7 +190,7 @@ static NTSTATUS unixdom_accept(struct socket_context *sock, } if (!(sock->flags & SOCKET_FLAG_BLOCK)) { - int ret = set_blocking(new_fd, False); + int ret = set_blocking(new_fd, false); if (ret == -1) { close(new_fd); return map_nt_error_from_unix(errno); diff --git a/source4/lib/socket_wrapper/socket_wrapper.c b/source4/lib/socket_wrapper/socket_wrapper.c index ec074ecaeb..c13cb6a3b0 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.c +++ b/source4/lib/socket_wrapper/socket_wrapper.c @@ -1288,7 +1288,7 @@ _PUBLIC_ int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen) return -1; } - my_addr = malloc(my_addrlen); + my_addr = (struct sockaddr *)malloc(my_addrlen); if (my_addr == NULL) { return -1; } diff --git a/source4/lib/socket_wrapper/socket_wrapper.h b/source4/lib/socket_wrapper/socket_wrapper.h index fd1e48610b..cc8b937608 100644 --- a/source4/lib/socket_wrapper/socket_wrapper.h +++ b/source4/lib/socket_wrapper/socket_wrapper.h @@ -37,6 +37,7 @@ #define __SOCKET_WRAPPER_H__ const char *socket_wrapper_dir(void); +unsigned int socket_wrapper_default_iface(void); int swrap_socket(int family, int type, int protocol); int swrap_accept(int s, struct sockaddr *addr, socklen_t *addrlen); int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t addrlen); @@ -131,4 +132,5 @@ int swrap_close(int); #define close(s) swrap_close(s) #endif + #endif /* __SOCKET_WRAPPER_H__ */ diff --git a/source4/lib/stream/packet.c b/source4/lib/stream/packet.c index e6cfae7bd6..51021c1fc6 100644 --- a/source4/lib/stream/packet.c +++ b/source4/lib/stream/packet.c @@ -39,13 +39,13 @@ struct packet_context { size_t packet_size; void *private; struct fd_event *fde; - BOOL serialise; + bool serialise; int processing; - BOOL recv_disable; - BOOL nofree; + bool recv_disable; + bool nofree; - BOOL busy; - BOOL destructor_called; + bool busy; + bool destructor_called; struct send_element { struct send_element *next, *prev; @@ -63,7 +63,7 @@ struct packet_context { static int packet_destructor(struct packet_context *pc) { if (pc->busy) { - pc->destructor_called = True; + pc->destructor_called = true; /* now we refuse the talloc_free() request. The free will happen again in the packet_recv() code */ return -1; @@ -156,7 +156,7 @@ _PUBLIC_ void packet_set_fde(struct packet_context *pc, struct fd_event *fde) */ _PUBLIC_ void packet_set_serialise(struct packet_context *pc) { - pc->serialise = True; + pc->serialise = true; } /* @@ -173,7 +173,7 @@ _PUBLIC_ void packet_set_initial_read(struct packet_context *pc, uint32_t initia */ _PUBLIC_ void packet_set_nofree(struct packet_context *pc) { - pc->nofree = True; + pc->nofree = true; } @@ -373,11 +373,11 @@ next_partial: pc->processing = 1; } - pc->busy = True; + pc->busy = true; status = pc->callback(pc->private, blob); - pc->busy = False; + pc->busy = false; if (pc->destructor_called) { talloc_free(pc); @@ -429,7 +429,7 @@ next_partial: _PUBLIC_ void packet_recv_disable(struct packet_context *pc) { EVENT_FD_NOT_READABLE(pc->fde); - pc->recv_disable = True; + pc->recv_disable = true; } /* @@ -438,7 +438,7 @@ _PUBLIC_ void packet_recv_disable(struct packet_context *pc) _PUBLIC_ void packet_recv_enable(struct packet_context *pc) { EVENT_FD_READABLE(pc->fde); - pc->recv_disable = False; + pc->recv_disable = false; if (pc->num_read != 0 && pc->packet_size >= pc->num_read) { event_add_timed(pc->ev, pc, timeval_zero(), packet_next_event, pc); } diff --git a/source4/lib/talloc/config.mk b/source4/lib/talloc/config.mk index 0f138aafcd..714ad72d1c 100644 --- a/source4/lib/talloc/config.mk +++ b/source4/lib/talloc/config.mk @@ -5,7 +5,7 @@ VERSION = 0.0.1 SO_VERSION = 0 OBJ_FILES = talloc.o MANPAGE = talloc.3 -CFLAGS = -I$(srcdir)/lib/talloc +CFLAGS = -Ilib/talloc PUBLIC_HEADERS = talloc.h DESCRIPTION = A hierarchical pool based memory system with destructors # diff --git a/source4/lib/talloc/configure.ac b/source4/lib/talloc/configure.ac index e1e84b25c3..afc2a944f0 100644 --- a/source4/lib/talloc/configure.ac +++ b/source4/lib/talloc/configure.ac @@ -1,5 +1,5 @@ AC_PREREQ(2.50) -AC_INIT(talloc, 1.0.1) +AC_INIT(talloc, 1.1.0) AC_CONFIG_SRCDIR([talloc.c]) AC_SUBST(datarootdir) AC_CONFIG_HEADER(config.h) diff --git a/source4/lib/talloc/talloc.c b/source4/lib/talloc/talloc.c index c073a8c774..4d72c0e871 100644 --- a/source4/lib/talloc/talloc.c +++ b/source4/lib/talloc/talloc.c @@ -1109,64 +1109,132 @@ void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name return newp; } +static inline char *__talloc_strlendup(const void *t, const char *p, size_t len) +{ + char *ret; + + ret = (char *)__talloc(t, len + 1); + if (unlikely(!ret)) return NULL; + + memcpy(ret, p, len); + ret[len] = 0; + + _talloc_set_name_const(ret, ret); + return ret; +} + /* - strdup with a talloc + strdup with a talloc */ char *talloc_strdup(const void *t, const char *p) { + if (unlikely(!p)) return NULL; + return __talloc_strlendup(t, p, strlen(p)); +} + +/* + strndup with a talloc +*/ +char *talloc_strndup(const void *t, const char *p, size_t n) +{ + if (unlikely(!p)) return NULL; + return __talloc_strlendup(t, p, strnlen(p, n)); +} + +static inline char *__talloc_strlendup_append(char *s, size_t slen, + const char *a, size_t alen) +{ char *ret; - if (!p) { - return NULL; + + ret = talloc_realloc(NULL, s, char, slen + alen + 1); + if (unlikely(!ret)) return NULL; + + /* append the string and the trailing \0 */ + memcpy(&ret[slen], a, alen); + ret[slen+alen] = 0; + + _talloc_set_name_const(ret, ret); + return ret; +} + +/* + * Appends at the end of the string. + */ +char *talloc_strdup_append(char *s, const char *a) +{ + if (unlikely(!s)) { + return talloc_strdup(NULL, a); } - ret = (char *)talloc_memdup(t, p, strlen(p) + 1); - if (likely(ret)) { - _talloc_set_name_const(ret, ret); + + if (unlikely(!a)) { + return s; } - return ret; + + return __talloc_strlendup_append(s, strlen(s), a, strlen(a)); } /* - append to a talloced string -*/ -char *talloc_append_string(const void *t, char *orig, const char *append) + * Appends at the end of the talloc'ed buffer, + * not the end of the string. + */ +char *talloc_strdup_append_buffer(char *s, const char *a) { - char *ret; - size_t olen = strlen(orig); - size_t alenz; + size_t slen; - if (!append) - return orig; + if (unlikely(!s)) { + return talloc_strdup(NULL, a); + } - alenz = strlen(append) + 1; + if (unlikely(!a)) { + return s; + } - ret = talloc_realloc(t, orig, char, olen + alenz); - if (!ret) - return NULL; + slen = talloc_get_size(s); + if (likely(slen > 0)) { + slen--; + } - /* append the string with the trailing \0 */ - memcpy(&ret[olen], append, alenz); + return __talloc_strlendup_append(s, slen, a, strlen(a)); +} - _talloc_set_name_const(ret, ret); +/* + * Appends at the end of the string. + */ +char *talloc_strndup_append(char *s, const char *a, size_t n) +{ + if (unlikely(!s)) { + return talloc_strdup(NULL, a); + } - return ret; + if (unlikely(!a)) { + return s; + } + + return __talloc_strlendup_append(s, strlen(s), a, strnlen(a, n)); } /* - strndup with a talloc -*/ -char *talloc_strndup(const void *t, const char *p, size_t n) + * Appends at the end of the talloc'ed buffer, + * not the end of the string. + */ +char *talloc_strndup_append_buffer(char *s, const char *a, size_t n) { - size_t len; - char *ret; + size_t slen; - for (len=0; len<n && p[len]; len++) ; + if (unlikely(!s)) { + return talloc_strdup(NULL, a); + } - ret = (char *)__talloc(t, len + 1); - if (!ret) { return NULL; } - memcpy(ret, p, len); - ret[len] = 0; - _talloc_set_name_const(ret, ret); - return ret; + if (unlikely(!a)) { + return s; + } + + slen = talloc_get_size(s); + if (likely(slen > 0)) { + slen--; + } + + return __talloc_strlendup_append(s, slen, a, strnlen(a, n)); } #ifndef HAVE_VA_COPY @@ -1188,18 +1256,18 @@ char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) va_copy(ap2, ap); len = vsnprintf(&c, 1, fmt, ap2); va_end(ap2); - if (len < 0) { + if (unlikely(len < 0)) { return NULL; } ret = (char *)__talloc(t, len+1); - if (ret) { - va_copy(ap2, ap); - vsnprintf(ret, len+1, fmt, ap2); - va_end(ap2); - _talloc_set_name_const(ret, ret); - } + if (unlikely(!ret)) return NULL; + + va_copy(ap2, ap); + vsnprintf(ret, len+1, fmt, ap2); + va_end(ap2); + _talloc_set_name_const(ret, ret); return ret; } @@ -1219,52 +1287,78 @@ char *talloc_asprintf(const void *t, const char *fmt, ...) return ret; } +static inline char *__talloc_vaslenprintf_append(char *s, size_t slen, + const char *fmt, va_list ap) + PRINTF_ATTRIBUTE(3,0); -/** - * Realloc @p s to append the formatted result of @p fmt and @p ap, - * and return @p s, which may have moved. Good for gradually - * accumulating output into a string buffer. - **/ -char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) -{ - struct talloc_chunk *tc; - int len, s_len; +static inline char *__talloc_vaslenprintf_append(char *s, size_t slen, + const char *fmt, va_list ap) +{ + ssize_t alen; va_list ap2; char c; - if (s == NULL) { - return talloc_vasprintf(NULL, fmt, ap); - } - - tc = talloc_chunk_from_ptr(s); - - s_len = tc->size - 1; - va_copy(ap2, ap); - len = vsnprintf(&c, 1, fmt, ap2); + alen = vsnprintf(&c, 1, fmt, ap2); va_end(ap2); - if (len <= 0) { + if (alen <= 0) { /* Either the vsnprintf failed or the format resulted in * no characters being formatted. In the former case, we * ought to return NULL, in the latter we ought to return - * the original string. Most current callers of this + * the original string. Most current callers of this * function expect it to never return NULL. */ return s; } - s = talloc_realloc(NULL, s, char, s_len + len+1); + s = talloc_realloc(NULL, s, char, slen + alen + 1); if (!s) return NULL; va_copy(ap2, ap); - vsnprintf(s+s_len, len+1, fmt, ap2); + vsnprintf(s + slen, alen + 1, fmt, ap2); va_end(ap2); - _talloc_set_name_const(s, s); + _talloc_set_name_const(s, s); return s; } +/** + * Realloc @p s to append the formatted result of @p fmt and @p ap, + * and return @p s, which may have moved. Good for gradually + * accumulating output into a string buffer. Appends at the end + * of the string. + **/ +char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) +{ + if (unlikely(!s)) { + return talloc_vasprintf(NULL, fmt, ap); + } + + return __talloc_vaslenprintf_append(s, strlen(s), fmt, ap); +} + +/** + * Realloc @p s to append the formatted result of @p fmt and @p ap, + * and return @p s, which may have moved. Always appends at the + * end of the talloc'ed buffer, not the end of the string. + **/ +char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) +{ + size_t slen; + + if (unlikely(!s)) { + return talloc_vasprintf(NULL, fmt, ap); + } + + slen = talloc_get_size(s); + if (likely(slen > 0)) { + slen--; + } + + return __talloc_vaslenprintf_append(s, slen, fmt, ap); +} + /* Realloc @p s to append the formatted result of @p fmt and return @p s, which may have moved. Good for gradually accumulating output @@ -1281,6 +1375,21 @@ char *talloc_asprintf_append(char *s, const char *fmt, ...) } /* + Realloc @p s to append the formatted result of @p fmt and return @p + s, which may have moved. Good for gradually accumulating output + into a buffer. + */ +char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + s = talloc_vasprintf_append_buffer(s, fmt, ap); + va_end(ap); + return s; +} + +/* alloc an array, checking for integer overflow in the array size */ void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name) diff --git a/source4/lib/talloc/talloc.h b/source4/lib/talloc/talloc.h index 15130d0d98..e103391681 100644 --- a/source4/lib/talloc/talloc.h +++ b/source4/lib/talloc/talloc.h @@ -111,6 +111,7 @@ typedef void TALLOC_CTX; #define talloc_array_p(ctx, type, count) talloc_array(ctx, type, count) #define talloc_realloc_p(ctx, p, type, count) talloc_realloc(ctx, p, type, count) #define talloc_destroy(ctx) talloc_free(ctx) +#define talloc_append_string(c, s, a) (s?talloc_strdup_append(s,a):talloc_strdup(c, a)) #endif /* The following definitions come from talloc.c */ @@ -152,13 +153,6 @@ void talloc_enable_leak_report(void); void talloc_enable_leak_report_full(void); void *_talloc_zero(const void *ctx, size_t size, const char *name); void *_talloc_memdup(const void *t, const void *p, size_t size, const char *name); -char *talloc_strdup(const void *t, const char *p); -char *talloc_strndup(const void *t, const char *p, size_t n); -char *talloc_append_string(const void *t, char *orig, const char *append); -char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); -char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); -char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); -char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); void *_talloc_array(const void *ctx, size_t el_size, unsigned count, const char *name); void *_talloc_zero_array(const void *ctx, size_t el_size, unsigned count, const char *name); void *_talloc_realloc_array(const void *ctx, void *ptr, size_t el_size, unsigned count, const char *name); @@ -169,4 +163,20 @@ void *talloc_find_parent_byname(const void *ctx, const char *name); void talloc_show_parents(const void *context, FILE *file); int talloc_is_parent(const void *context, const void *ptr); +char *talloc_strdup(const void *t, const char *p); +char *talloc_strdup_append(char *s, const char *a); +char *talloc_strdup_append_buffer(char *s, const char *a); + +char *talloc_strndup(const void *t, const char *p, size_t n); +char *talloc_strndup_append(char *s, const char *a, size_t n); +char *talloc_strndup_append_buffer(char *s, const char *a, size_t n); + +char *talloc_vasprintf(const void *t, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); +char *talloc_vasprintf_append(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); +char *talloc_vasprintf_append_buffer(char *s, const char *fmt, va_list ap) PRINTF_ATTRIBUTE(2,0); + +char *talloc_asprintf(const void *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); +char *talloc_asprintf_append(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); +char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); + #endif diff --git a/source4/lib/talloc/talloc_guide.txt b/source4/lib/talloc/talloc_guide.txt index c4634ae19a..18663b370d 100644 --- a/source4/lib/talloc/talloc_guide.txt +++ b/source4/lib/talloc/talloc_guide.txt @@ -568,8 +568,23 @@ string. This is equivalent to: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- char *talloc_asprintf_append(char *s, const char *fmt, ...); +The talloc_asprintf_append() function appends the given formatted +string to the given string. +Use this varient when the string in the current talloc buffer may +have been truncated in length. + +This functions sets the name of the new pointer to the new +string. This is equivalent to: + talloc_set_name_const(ptr, ptr) + + +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +char *talloc_asprintf_append_buffer(char *s, const char *fmt, ...); + The talloc_asprintf_append() function appends the given formatted -string to the given string. +string to the end of the currently allocated talloc buffer. +Use this varient when the string in the current talloc buffer has +not been changed. This functions sets the name of the new pointer to the new string. This is equivalent to: @@ -577,7 +592,7 @@ string. This is equivalent to: =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -(type *)talloc_array(const void *ctx, type, uint_t count); +((type *)talloc_array(const void *ctx, type, uint_t count); The talloc_array() macro is equivalent to: diff --git a/source4/lib/talloc/testsuite.c b/source4/lib/talloc/testsuite.c index ddf6865b1a..e16c91f8b9 100644 --- a/source4/lib/talloc/testsuite.c +++ b/source4/lib/talloc/testsuite.c @@ -419,15 +419,15 @@ static bool test_misc(void) p2 = talloc_strndup(p1, "foo", 2); torture_assert("misc", strcmp("fo", p2) == 0, "strndup doesn't work\n"); - p2 = talloc_asprintf_append(p2, "o%c", 'd'); + p2 = talloc_asprintf_append_buffer(p2, "o%c", 'd'); torture_assert("misc", strcmp("food", p2) == 0, - "talloc_asprintf_append doesn't work\n"); + "talloc_asprintf_append_buffer doesn't work\n"); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 3); - p2 = talloc_asprintf_append(NULL, "hello %s", "world"); + p2 = talloc_asprintf_append_buffer(NULL, "hello %s", "world"); torture_assert("misc", strcmp("hello world", p2) == 0, - "talloc_asprintf_append doesn't work\n"); + "talloc_asprintf_append_buffer doesn't work\n"); CHECK_BLOCKS("misc", p2, 1); CHECK_BLOCKS("misc", p1, 3); talloc_free(p2); diff --git a/source4/lib/tdb/swig/Tdb.py b/source4/lib/tdb/swig/Tdb.py index 529d0753d1..d1a506e69c 100644 --- a/source4/lib/tdb/swig/Tdb.py +++ b/source4/lib/tdb/swig/Tdb.py @@ -69,7 +69,7 @@ class Tdb: tdb_delete(self.tdb, key) def has_key(self, key): - return tdb_exists(self.tdb, key) + return tdb_exists(self.tdb, key) != 0 # Tdb iterator @@ -113,3 +113,7 @@ class Tdb: def clear(self): for k in iter(self): del(self[k]) + + # TODO: iterkeys, itervalues, iteritems + + # TODO: any other missing methods for container types diff --git a/source4/lib/tdb/swig/tdb.i b/source4/lib/tdb/swig/tdb.i index fbb0f29dec..1ff21f53b5 100644 --- a/source4/lib/tdb/swig/tdb.i +++ b/source4/lib/tdb/swig/tdb.i @@ -102,7 +102,21 @@ typedef int mode_t; #define TDB_CONVERT 16 /* convert endian (internal use) */ #define TDB_BIGENDIAN 32 /* header is big-endian (internal use) */ -/* Throw an IOError exception if tdb_open() or tdb_open_ex() returns NULL */ +enum TDB_ERROR { + TDB_SUCCESS=0, + TDB_ERR_CORRUPT, + TDB_ERR_IO, + TDB_ERR_LOCK, + TDB_ERR_OOM, + TDB_ERR_EXISTS, + TDB_ERR_NOLOCK, + TDB_ERR_LOCK_TIMEOUT, + TDB_ERR_NOEXIST, + TDB_ERR_EINVAL, + TDB_ERR_RDONLY +}; + +/* Throw an IOError exception from errno if tdb_open() returns NULL */ %exception { $action @@ -115,19 +129,8 @@ typedef int mode_t; TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode); -TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, - int open_flags, mode_t mode, - tdb_log_func log_fn, - tdb_hash_func hash_fn); - %exception; -int tdb_reopen(TDB_CONTEXT *tdb); - -int tdb_reopen_all(int parent_longlived); - -void tdb_logging_function(TDB_CONTEXT *tdb, tdb_log_func); - enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb); const char *tdb_errorstr(TDB_CONTEXT *tdb); @@ -146,22 +149,4 @@ TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb); TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA key); -int tdb_traverse(TDB_CONTEXT *tdb, tdb_traverse_func fn, void *state); - int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); - -int tdb_lockall(TDB_CONTEXT *tdb); - -void tdb_unlockall(TDB_CONTEXT *tdb); - -/* Low level locking functions: use with care */ - -int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key); - -int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key); - -/* Debug functions. Not used in production. */ - -void tdb_dump_all(TDB_CONTEXT *tdb); - -int tdb_printfreelist(TDB_CONTEXT *tdb); diff --git a/source4/lib/tdb/tools/tdbtorture.c b/source4/lib/tdb/tools/tdbtorture.c index 14a2b48cdc..ca71c736ad 100644 --- a/source4/lib/tdb/tools/tdbtorture.c +++ b/source4/lib/tdb/tools/tdbtorture.c @@ -238,7 +238,7 @@ static void usage(void) unlink("torture.tdb"); - pids = calloc(sizeof(pid_t), num_procs); + pids = (pid_t *)calloc(sizeof(pid_t), num_procs); pids[0] = getpid(); for (i=0;i<num_procs-1;i++) { diff --git a/source4/lib/tls/tls.c b/source4/lib/tls/tls.c index bfe144a011..4a8357d93b 100644 --- a/source4/lib/tls/tls.c +++ b/source4/lib/tls/tls.c @@ -24,6 +24,8 @@ #include "includes.h" #include "lib/events/events.h" #include "lib/socket/socket.h" +#include "lib/tls/tls.h" +#include "param/param.h" #if ENABLE_GNUTLS #include "gnutls/gnutls.h" @@ -38,7 +40,7 @@ typedef gnutls_datum gnutls_datum_t; struct tls_params { gnutls_certificate_credentials x509_cred; gnutls_dh_params dh_params; - BOOL tls_enabled; + bool tls_enabled; }; #endif @@ -46,32 +48,32 @@ struct tls_params { struct tls_context { struct socket_context *socket; struct fd_event *fde; - BOOL tls_enabled; + bool tls_enabled; #if ENABLE_GNUTLS gnutls_session session; - BOOL done_handshake; - BOOL have_first_byte; + bool done_handshake; + bool have_first_byte; uint8_t first_byte; - BOOL tls_detect; + bool tls_detect; const char *plain_chars; - BOOL output_pending; + bool output_pending; gnutls_certificate_credentials xcred; - BOOL interrupted; + bool interrupted; #endif }; -BOOL tls_enabled(struct socket_context *sock) +bool tls_enabled(struct socket_context *sock) { struct tls_context *tls; if (!sock) { - return False; + return false; } if (strcmp(sock->backend_name, "tls") != 0) { - return False; + return false; } tls = talloc_get_type(sock->private_data, struct tls_context); if (!tls) { - return False; + return false; } return tls->tls_enabled; } @@ -115,7 +117,7 @@ static ssize_t tls_pull(gnutls_transport_ptr ptr, void *buf, size_t size) if (tls->have_first_byte) { *(uint8_t *)buf = tls->first_byte; - tls->have_first_byte = False; + tls->have_first_byte = false; return 1; } @@ -211,7 +213,7 @@ static NTSTATUS tls_handshake(struct tls_context *tls) DEBUG(0,("TLS gnutls_handshake failed - %s\n", gnutls_strerror(ret))); return NT_STATUS_UNEXPECTED_NETWORK_ERROR; } - tls->done_handshake = True; + tls->done_handshake = true; return NT_STATUS_OK; } @@ -233,7 +235,7 @@ static NTSTATUS tls_interrupted(struct tls_context *tls) if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { return STATUS_MORE_ENTRIES; } - tls->interrupted = False; + tls->interrupted = false; return NT_STATUS_OK; } @@ -272,15 +274,15 @@ static NTSTATUS tls_socket_recv(struct socket_context *sock, void *buf, status = socket_recv(tls->socket, &tls->first_byte, 1, nread); NT_STATUS_NOT_OK_RETURN(status); if (*nread == 0) return NT_STATUS_OK; - tls->tls_detect = False; + tls->tls_detect = false; /* look for the first byte of a valid HTTP operation */ if (strchr(tls->plain_chars, tls->first_byte)) { /* not a tls link */ - tls->tls_enabled = False; + tls->tls_enabled = false; *(uint8_t *)buf = tls->first_byte; return NT_STATUS_OK; } - tls->have_first_byte = True; + tls->have_first_byte = true; } if (!tls->tls_enabled) { @@ -298,7 +300,7 @@ static NTSTATUS tls_socket_recv(struct socket_context *sock, void *buf, if (gnutls_record_get_direction(tls->session) == 1) { EVENT_FD_WRITEABLE(tls->fde); } - tls->interrupted = True; + tls->interrupted = true; return STATUS_MORE_ENTRIES; } if (ret < 0) { @@ -334,7 +336,7 @@ static NTSTATUS tls_socket_send(struct socket_context *sock, if (gnutls_record_get_direction(tls->session) == 1) { EVENT_FD_WRITEABLE(tls->fde); } - tls->interrupted = True; + tls->interrupted = true; return STATUS_MORE_ENTRIES; } if (ret < 0) { @@ -355,11 +357,11 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx) struct tls_params *params; int ret; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - const char *keyfile = private_path(tmp_ctx, lp_tls_keyfile()); - const char *certfile = private_path(tmp_ctx, lp_tls_certfile()); - const char *cafile = private_path(tmp_ctx, lp_tls_cafile()); - const char *crlfile = private_path(tmp_ctx, lp_tls_crlfile()); - const char *dhpfile = private_path(tmp_ctx, lp_tls_dhpfile()); + const char *keyfile = private_path(tmp_ctx, global_loadparm, lp_tls_keyfile(global_loadparm)); + const char *certfile = private_path(tmp_ctx, global_loadparm, lp_tls_certfile(global_loadparm)); + const char *cafile = private_path(tmp_ctx, global_loadparm, lp_tls_cafile(global_loadparm)); + const char *crlfile = private_path(tmp_ctx, global_loadparm, lp_tls_crlfile(global_loadparm)); + const char *dhpfile = private_path(tmp_ctx, global_loadparm, lp_tls_dhpfile(global_loadparm)); void tls_cert_generate(TALLOC_CTX *, const char *, const char *, const char *); params = talloc(mem_ctx, struct tls_params); @@ -368,8 +370,8 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx) return NULL; } - if (!lp_tls_enabled() || keyfile == NULL || *keyfile == 0) { - params->tls_enabled = False; + if (!lp_tls_enabled(global_loadparm) || keyfile == NULL || *keyfile == 0) { + params->tls_enabled = false; talloc_free(tmp_ctx); return params; } @@ -436,14 +438,14 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx) gnutls_certificate_set_dh_params(params->x509_cred, params->dh_params); - params->tls_enabled = True; + params->tls_enabled = true; talloc_free(tmp_ctx); return params; init_failed: DEBUG(0,("GNUTLS failed to initialise - %s\n", gnutls_strerror(ret))); - params->tls_enabled = False; + params->tls_enabled = false; talloc_free(tmp_ctx); return params; } @@ -508,16 +510,16 @@ struct socket_context *tls_init_server(struct tls_params *params, tls->plain_chars = plain_chars; if (plain_chars) { - tls->tls_detect = True; + tls->tls_detect = true; } else { - tls->tls_detect = False; + tls->tls_detect = false; } - tls->output_pending = False; - tls->done_handshake = False; - tls->have_first_byte = False; - tls->tls_enabled = True; - tls->interrupted = False; + tls->output_pending = false; + tls->done_handshake = false; + tls->have_first_byte = false; + tls->tls_enabled = true; + tls->interrupted = false; new_sock->state = SOCKET_STATE_SERVER_CONNECTED; @@ -563,7 +565,7 @@ struct socket_context *tls_init_client(struct socket_context *socket, } new_sock->private_data = tls; - cafile = private_path(tls, lp_tls_cafile()); + cafile = private_path(tls, global_loadparm, lp_tls_cafile(global_loadparm)); if (!cafile || !*cafile) { goto failed; } @@ -584,13 +586,13 @@ struct socket_context *tls_init_client(struct socket_context *socket, gnutls_transport_set_pull_function(tls->session, (gnutls_pull_func)tls_pull); gnutls_transport_set_push_function(tls->session, (gnutls_push_func)tls_push); gnutls_transport_set_lowat(tls->session, 0); - tls->tls_detect = False; + tls->tls_detect = false; - tls->output_pending = False; - tls->done_handshake = False; - tls->have_first_byte = False; - tls->tls_enabled = True; - tls->interrupted = False; + tls->output_pending = false; + tls->done_handshake = false; + tls->have_first_byte = false; + tls->tls_enabled = true; + tls->interrupted = false; new_sock->state = SOCKET_STATE_CLIENT_CONNECTED; @@ -598,7 +600,7 @@ struct socket_context *tls_init_client(struct socket_context *socket, failed: DEBUG(0,("TLS init connection failed - %s\n", gnutls_strerror(ret))); - tls->tls_enabled = False; + tls->tls_enabled = false; return new_sock; } @@ -647,7 +649,7 @@ static const struct socket_ops tls_socket_ops = { .fn_get_fd = tls_socket_get_fd }; -BOOL tls_support(struct tls_params *params) +bool tls_support(struct tls_params *params) { return params->tls_enabled; } @@ -683,9 +685,9 @@ struct socket_context *tls_init_client(struct socket_context *socket, return NULL; } -BOOL tls_support(struct tls_params *params) +bool tls_support(struct tls_params *params) { - return False; + return false; } #endif diff --git a/source4/lib/tls/tlscert.c b/source4/lib/tls/tlscert.c index ad65df0e6c..240ae056c1 100644 --- a/source4/lib/tls/tlscert.c +++ b/source4/lib/tls/tlscert.c @@ -153,5 +153,5 @@ failed: } #else - void tls_cert_dummy(void) {} +void tls_cert_dummy(void) {} #endif diff --git a/source4/lib/util/attr.h b/source4/lib/util/attr.h new file mode 100644 index 0000000000..8f6c4f5d8a --- /dev/null +++ b/source4/lib/util/attr.h @@ -0,0 +1,92 @@ +/* + Unix SMB/CIFS implementation. + Samba utility functions + Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007 + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __UTIL_ATTR_H__ +#define __UTIL_ATTR_H__ + +#ifdef __GNUC__ +/** gcc attribute used on function parameters so that it does not emit + * warnings about them being unused. **/ +# define UNUSED(param) param __attribute__ ((unused)) +#else +# define UNUSED(param) param +/** Feel free to add definitions for other compilers here. */ +#endif + +#ifndef _PUBLIC_ +#ifdef HAVE_VISIBILITY_ATTR +# define _PUBLIC_ __attribute__((visibility("default"))) +#else +# define _PUBLIC_ +#endif +#endif + +#ifndef _DEPRECATED_ +#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) +#define _DEPRECATED_ __attribute__ ((deprecated)) +#else +#define _DEPRECATED_ +#endif +#endif + +#ifndef _WARN_UNUSED_RESULT_ +#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) +#define _WARN_UNUSED_RESULT_ __attribute__ ((warn_unused_result)) +#else +#define _WARN_UNUSED_RESULT_ +#endif +#endif + +#ifndef _NORETURN_ +#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1 ) +#define _NORETURN_ __attribute__ ((noreturn)) +#else +#define _NORETURN_ +#endif +#endif + +#ifndef _PURE_ +#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1) +#define _PURE_ __attribute__((pure)) +#else +#define _PURE_ +#endif +#endif + +#ifndef NONNULL +#if (__GNUC__ >= 3) && (__GNUC_MINOR__ >= 1) +#define NONNULL(param) param __attribute__((nonnull)) +#else +#define NONNULL(param) param +#endif +#endif + +#ifndef PRINTF_ATTRIBUTE +#if __GNUC__ >= 3 +/** Use gcc attribute to check printf fns. a1 is the 1-based index of + * the parameter containing the format, and a2 the index of the first + * argument. Note that some gcc 2.x versions don't handle this + * properly **/ +#define PRINTF_ATTRIBUTE(a1, a2) __attribute__ ((format (__printf__, a1, a2))) +#else +#define PRINTF_ATTRIBUTE(a1, a2) +#endif +#endif + +#endif /* __UTIL_ATTR_H__ */ diff --git a/source4/lib/util/config.mk b/source4/lib/util/config.mk index 702e3df5aa..0691bd7889 100644 --- a/source4/lib/util/config.mk +++ b/source4/lib/util/config.mk @@ -3,6 +3,7 @@ #SO_VERSION = 0 #DESCRIPTION = Generic utility functions PUBLIC_HEADERS = util.h \ + attr.h \ byteorder.h \ data_blob.h \ debug.h \ @@ -31,7 +32,7 @@ OBJ_FILES = xfile.o \ PUBLIC_DEPENDENCIES = \ LIBTALLOC LIBCRYPTO \ SOCKET_WRAPPER EXT_NSL \ - CHARSET + CHARSET EXECINFO [SUBSYSTEM::UNIX_PRIVS] PRIVATE_PROTO_HEADER = unix_privs.h diff --git a/source4/lib/util/data_blob.c b/source4/lib/util/data_blob.c index 117043f95c..b258e47bba 100644 --- a/source4/lib/util/data_blob.c +++ b/source4/lib/util/data_blob.c @@ -39,9 +39,9 @@ _PUBLIC_ DATA_BLOB data_blob_named(const void *p, size_t length, const char *nam } if (p) { - ret.data = talloc_memdup(NULL, p, length); + ret.data = (uint8_t *)talloc_memdup(NULL, p, length); } else { - ret.data = talloc_size(NULL, length); + ret.data = talloc_array(NULL, uint8_t, length); } if (ret.data == NULL) { ret.length = 0; @@ -175,7 +175,7 @@ _PUBLIC_ char *data_blob_hex_string(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob) _PUBLIC_ DATA_BLOB data_blob_string_const(const char *str) { DATA_BLOB blob; - blob.data = discard_const(str); + blob.data = discard_const_p(uint8_t, str); blob.length = strlen(str); return blob; } @@ -187,7 +187,7 @@ _PUBLIC_ DATA_BLOB data_blob_string_const(const char *str) _PUBLIC_ DATA_BLOB data_blob_const(const void *p, size_t length) { DATA_BLOB blob; - blob.data = discard_const(p); + blob.data = discard_const_p(uint8_t, p); blob.length = length; return blob; } @@ -198,7 +198,7 @@ _PUBLIC_ DATA_BLOB data_blob_const(const void *p, size_t length) **/ _PUBLIC_ bool data_blob_realloc(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, size_t length) { - blob->data = talloc_realloc_size(mem_ctx, blob->data, length); + blob->data = talloc_realloc(mem_ctx, blob->data, uint8_t, length); if (blob->data == NULL) return false; blob->length = length; diff --git a/source4/lib/util/data_blob.h b/source4/lib/util/data_blob.h index e39b2eaf45..1442438dd7 100644 --- a/source4/lib/util/data_blob.h +++ b/source4/lib/util/data_blob.h @@ -24,6 +24,7 @@ #endif #include <talloc.h> +#include <stdint.h> /* used to hold an arbitrary blob of data */ typedef struct datablob { diff --git a/source4/lib/util/dprintf.c b/source4/lib/util/dprintf.c index a7770f364d..91665e7bdd 100644 --- a/source4/lib/util/dprintf.c +++ b/source4/lib/util/dprintf.c @@ -48,7 +48,7 @@ _PUBLIC_ int d_vfprintf(FILE *f, const char *format, va_list ap) _PRINTF_ATTRIBU charset, but beware of it growing */ maxlen = ret*2; again: - p2 = malloc(maxlen); + p2 = (char *)malloc(maxlen); if (!p2) { SAFE_FREE(p); return -1; diff --git a/source4/lib/util/fault.c b/source4/lib/util/fault.c index 5cc9445407..e9cd040ee6 100644 --- a/source4/lib/util/fault.c +++ b/source4/lib/util/fault.c @@ -153,7 +153,7 @@ _PUBLIC_ _NORETURN_ void smb_panic(const char *why) /** report a fault **/ -static void fault_report(int sig) +_NORETURN_ static void fault_report(int sig) { static int counter; @@ -172,7 +172,7 @@ static void fault_report(int sig) /** catch serious errors **/ -static void sig_fault(int sig) +_NORETURN_ static void sig_fault(int sig) { if (fault_handlers.fault_handler) { /* we have a fault handler, call it. It may not return. */ diff --git a/source4/lib/util/fault.m4 b/source4/lib/util/fault.m4 index 6d2c4f2a6a..b24e63641c 100644 --- a/source4/lib/util/fault.m4 +++ b/source4/lib/util/fault.m4 @@ -1,2 +1,5 @@ -AC_CHECK_HEADER(execinfo.h) -AC_CHECK_FUNCS(backtrace) +AC_CHECK_HEADERS(execinfo.h) +AC_SEARCH_LIBS_EXT(backtrace, [execinfo], EXECINFO_LIBS) +AC_CHECK_FUNC_EXT(backtrace, $EXECINFO_LIBS) +SMB_EXT_LIB(EXECINFO,[${EXECINFO_LIBS}]) +SMB_ENABLE(EXECINFO) diff --git a/source4/lib/util/ms_fnmatch.c b/source4/lib/util/ms_fnmatch.c index 8e216b0226..73fb0e0966 100644 --- a/source4/lib/util/ms_fnmatch.c +++ b/source4/lib/util/ms_fnmatch.c @@ -201,11 +201,10 @@ int ms_fnmatch(const char *pattern, const char *string, enum protocol_types prot if (pattern[i] == '*' || pattern[i] == '<') count++; } - max_n = talloc_array(NULL, struct max_n, count); - if (!max_n) { + max_n = talloc_zero_array(NULL, struct max_n, count); + if (max_n == NULL) { return -1; } - memset(max_n, 0, sizeof(struct max_n) * count); ret = ms_fnmatch_core(pattern, string, max_n, strrchr(string, '.')); diff --git a/source4/lib/util/tests/file.c b/source4/lib/util/tests/file.c index 0fe117a300..fe87293671 100644 --- a/source4/lib/util/tests/file.c +++ b/source4/lib/util/tests/file.c @@ -88,10 +88,10 @@ struct torture_suite *torture_local_util_file(TALLOC_CTX *mem_ctx) struct torture_suite *suite = torture_suite_create(mem_ctx, "FILE"); torture_suite_add_simple_test(suite, "file_load_save", - test_file_load_save); + test_file_load_save); torture_suite_add_simple_test(suite, "afdgets", - test_afdgets); + test_afdgets); return suite; } diff --git a/source4/lib/util/tests/str.c b/source4/lib/util/tests/str.c new file mode 100644 index 0000000000..a219ef0891 --- /dev/null +++ b/source4/lib/util/tests/str.c @@ -0,0 +1,121 @@ +/* + Unix SMB/CIFS implementation. + + util_str testing + + Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007 + + 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 3 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, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "torture/ui.h" + +static bool test_string_sub_simple(struct torture_context *tctx) +{ + char tmp[100]; + safe_strcpy(tmp, "foobar", sizeof(tmp)); + string_sub(tmp, "foo", "bar", sizeof(tmp)); + torture_assert_str_equal(tctx, tmp, "barbar", "invalid sub"); + return true; +} + +static bool test_string_sub_multiple(struct torture_context *tctx) +{ + char tmp[100]; + safe_strcpy(tmp, "fooblafoo", sizeof(tmp)); + string_sub(tmp, "foo", "bar", sizeof(tmp)); + torture_assert_str_equal(tctx, tmp, "barblabar", "invalid sub"); + return true; +} + +static bool test_string_sub_longer(struct torture_context *tctx) +{ + char tmp[100]; + safe_strcpy(tmp, "foobla", sizeof(tmp)); + string_sub(tmp, "foo", "blie", sizeof(tmp)); + torture_assert_str_equal(tctx, tmp, "bliebla", "invalid sub"); + return true; +} + +static bool test_string_sub_shorter(struct torture_context *tctx) +{ + char tmp[100]; + safe_strcpy(tmp, "foobla", sizeof(tmp)); + string_sub(tmp, "foo", "bl", sizeof(tmp)); + torture_assert_str_equal(tctx, tmp, "blbla", "invalid sub"); + return true; +} + +static bool test_string_sub_special_char(struct torture_context *tctx) +{ + char tmp[100]; + safe_strcpy(tmp, "foobla", sizeof(tmp)); + string_sub(tmp, "foo", "%b;l", sizeof(tmp)); + torture_assert_str_equal(tctx, tmp, "_b_lbla", "invalid sub"); + return true; +} + +static bool test_string_sub_talloc_simple(struct torture_context *tctx) +{ + char *t; + + t = string_sub_talloc(tctx, "foobla", "foo", "bl"); + + torture_assert_str_equal(tctx, t, "blbla", "invalid sub"); + + return true; +} + +static bool test_string_sub_talloc_multiple(struct torture_context *tctx) +{ + char *t; + + t = string_sub_talloc(tctx, "fooblafoo", "foo", "aapnootmies"); + + torture_assert_str_equal(tctx, t, "aapnootmiesblaaapnootmies", + "invalid sub"); + + return true; +} + + + +struct torture_suite *torture_local_util_str(TALLOC_CTX *mem_ctx) +{ + struct torture_suite *suite = torture_suite_create(mem_ctx, "STR"); + + torture_suite_add_simple_test(suite, "string_sub_simple", + test_string_sub_simple); + + torture_suite_add_simple_test(suite, "string_sub_multiple", + test_string_sub_multiple); + + torture_suite_add_simple_test(suite, "string_sub_shorter", + test_string_sub_shorter); + + torture_suite_add_simple_test(suite, "string_sub_longer", + test_string_sub_longer); + + torture_suite_add_simple_test(suite, "string_sub_special_chars", + test_string_sub_special_char); + + torture_suite_add_simple_test(suite, "string_sub_talloc_simple", + test_string_sub_talloc_simple); + + torture_suite_add_simple_test(suite, "string_sub_talloc_multiple", + test_string_sub_talloc_multiple); + + return suite; +} diff --git a/source4/lib/util/tests/strlist.c b/source4/lib/util/tests/strlist.c index 41accd4bd2..437d9d741a 100644 --- a/source4/lib/util/tests/strlist.c +++ b/source4/lib/util/tests/strlist.c @@ -35,7 +35,7 @@ static const char *test_lists_shell_strings[] = { static bool test_lists_shell(struct torture_context *tctx, const void *test_data) { - const char *data = test_data; + const char *data = (const char *)test_data; const char **ret1, **ret2, *tmp; bool match = true; TALLOC_CTX *mem_ctx = tctx; diff --git a/source4/lib/util/time.c b/source4/lib/util/time.c index c800fffea0..fc51498009 100644 --- a/source4/lib/util/time.c +++ b/source4/lib/util/time.c @@ -269,7 +269,7 @@ _PUBLIC_ time_t pull_dos_date2(const uint8_t *date_ptr, int zone_offset) x2 = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16); SIVAL(&x,0,x2); - return pull_dos_date((void *)&x, zone_offset); + return pull_dos_date((const uint8_t *)&x, zone_offset); } /** @@ -374,14 +374,6 @@ _PUBLIC_ NTTIME pull_nttime(uint8_t *base, uint16_t offset) } /** - parse a nttime as a large integer in a string and return a NTTIME -*/ -_PUBLIC_ NTTIME nttime_from_string(const char *s) -{ - return strtoull(s, NULL, 0); -} - -/** return (tv1 - tv2) in microseconds */ _PUBLIC_ int64_t usec_time_diff(struct timeval *tv1, struct timeval *tv2) diff --git a/source4/lib/util/time.h b/source4/lib/util/time.h index a1b3facf24..557c5d4eab 100644 --- a/source4/lib/util/time.h +++ b/source4/lib/util/time.h @@ -19,6 +19,10 @@ #ifndef _SAMBA_TIME_H_ #define _SAMBA_TIME_H_ +#ifndef _PUBLIC_ +#define _PUBLIC_ +#endif + /* 64 bit time (100 nanosec) 1601 - cifs6.txt, section 3.5, page 30, 4 byte aligned */ typedef uint64_t NTTIME; diff --git a/source4/lib/util/util.c b/source4/lib/util/util.c index aa7a571585..624315f99e 100644 --- a/source4/lib/util/util.c +++ b/source4/lib/util/util.c @@ -190,28 +190,27 @@ _PUBLIC_ void msleep(unsigned int t) Get my own name, return in malloc'ed storage. **/ -_PUBLIC_ char* get_myname(void) +_PUBLIC_ char *get_myname(void) { char *hostname; - const int host_name_max = 255; char *p; - hostname = malloc(host_name_max+1); + hostname = (char *)malloc(MAXHOSTNAMELEN+1); *hostname = 0; /* get my host name */ - if (gethostname(hostname, host_name_max+1) == -1) { + if (gethostname(hostname, MAXHOSTNAMELEN+1) == -1) { DEBUG(0,("gethostname failed\n")); return NULL; } /* Ensure null termination. */ - hostname[host_name_max] = '\0'; + hostname[MAXHOSTNAMELEN] = '\0'; /* split off any parts after an initial . */ - p = strchr(hostname,'.'); + p = strchr(hostname, '.'); - if (p) + if (p != NULL) *p = 0; return hostname; diff --git a/source4/lib/util/util.h b/source4/lib/util/util.h index 8259e08512..1960aa6196 100644 --- a/source4/lib/util/util.h +++ b/source4/lib/util/util.h @@ -28,12 +28,12 @@ * @brief Helpful macros */ -struct substitute_context; struct smbsrv_tcon; extern const char *logfile; extern const char *panic_action; +#include "util/attr.h" #include "util/time.h" #include "util/data_blob.h" #include "util/xfile.h" @@ -73,7 +73,7 @@ extern const char *panic_action; */ #define SMB_ASSERT(b) do { if (!(b)) { \ DEBUG(0,("PANIC: assert failed at %s(%d)\n", __FILE__, __LINE__)); \ - smb_panic("assert failed"); abort(); }} while (0) + smb_panic("assert failed"); }} while (0) #ifndef SAFE_FREE /* Oh no this is also defined in tdb.h */ /** @@ -165,7 +165,7 @@ _PUBLIC_ void do_debug_header(int level, const char *location, const char *func) @note You should never have to call this function directly. Call the DEBUG() macro instead. */ -_PUBLIC_ void do_debug(const char *format, ...) _PRINTF_ATTRIBUTE(1,2); +_PUBLIC_ void do_debug(const char *format, ...) PRINTF_ATTRIBUTE(1,2); /** reopen the log file (usually called because the log file name might have changed) @@ -313,9 +313,9 @@ _PUBLIC_ char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len); /* The following definitions come from lib/util/dprintf.c */ -_PUBLIC_ int d_vfprintf(FILE *f, const char *format, va_list ap) _PRINTF_ATTRIBUTE(2,0); -_PUBLIC_ int d_fprintf(FILE *f, const char *format, ...) _PRINTF_ATTRIBUTE(2,3); -_PUBLIC_ int d_printf(const char *format, ...) _PRINTF_ATTRIBUTE(1,2); +_PUBLIC_ int d_vfprintf(FILE *f, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0); +_PUBLIC_ int d_fprintf(FILE *f, const char *format, ...) PRINTF_ATTRIBUTE(2,3); +_PUBLIC_ int d_printf(const char *format, ...) PRINTF_ATTRIBUTE(1,2); _PUBLIC_ void display_set_stderr(void); /* The following definitions come from lib/util/util_str.c */ @@ -371,17 +371,6 @@ _PUBLIC_ void hex_encode(const unsigned char *buff_in, size_t len, char **out_he _PUBLIC_ char *hex_encode_talloc(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len); /** - Free a string value. -**/ -_PUBLIC_ void string_free(char **s); - -/** - Set a string value, deallocating any existing space, and allocing the space - for the string -**/ -_PUBLIC_ bool string_set(char **dest, const char *src); - -/** Substitute a string for a pattern in another string. Make sure there is enough room! @@ -394,6 +383,10 @@ _PUBLIC_ bool string_set(char **dest, const char *src); **/ _PUBLIC_ void string_sub(char *s,const char *pattern, const char *insert, size_t len); + +_PUBLIC_ char *string_sub_talloc(TALLOC_CTX *mem_ctx, const char *s, + const char *pattern, const char *insert); + /** Similar to string_sub() but allows for any character to be substituted. Use with caution! @@ -562,11 +555,6 @@ _PUBLIC_ bool str_list_check(const char **list, const char *s); */ _PUBLIC_ bool str_list_check_ci(const char **list, const char *s); -/** - Check if a string is part of a list. -**/ -_PUBLIC_ bool in_list(const char *s, const char *list, bool casesensitive); - /* The following definitions come from lib/util/util_file.c */ @@ -620,8 +608,8 @@ _PUBLIC_ void file_lines_slashcont(char **lines); save a lump of data into a file. Mostly used for debugging */ _PUBLIC_ bool file_save(const char *fname, const void *packet, size_t length); -_PUBLIC_ int vfdprintf(int fd, const char *format, va_list ap) _PRINTF_ATTRIBUTE(2,0); -_PUBLIC_ int fdprintf(int fd, const char *format, ...) _PRINTF_ATTRIBUTE(2,3); +_PUBLIC_ int vfdprintf(int fd, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0); +_PUBLIC_ int fdprintf(int fd, const char *format, ...) PRINTF_ATTRIBUTE(2,3); _PUBLIC_ bool large_file_support(const char *path); /* The following definitions come from lib/util/util.c */ @@ -790,8 +778,6 @@ enum protocol_types { PROTOCOL_SMB2 }; - - int ms_fnmatch(const char *pattern, const char *string, enum protocol_types protocol); /** a generic fnmatch function - uses for non-CIFS pattern matching */ @@ -848,6 +834,6 @@ _PUBLIC_ int idr_remove(struct idr_context *idp, int id); /** Become a daemon, discarding the controlling terminal. **/ -_PUBLIC_ void become_daemon(bool Fork); +_PUBLIC_ void become_daemon(bool fork); #endif /* _SAMBA_UTIL_H_ */ diff --git a/source4/lib/util/util_pw.c b/source4/lib/util/util_pw.c index 0e0675571e..11e46ec4e3 100644 --- a/source4/lib/util/util_pw.c +++ b/source4/lib/util/util_pw.c @@ -21,37 +21,26 @@ #include "includes.h" -static struct passwd *alloc_copy_passwd(const struct passwd *from) +static struct passwd *alloc_copy_passwd(TALLOC_CTX *mem_ctx, + const struct passwd *from) { - struct passwd *ret = smb_xmalloc_p(struct passwd); - ZERO_STRUCTP(ret); - ret->pw_name = smb_xstrdup(from->pw_name); - ret->pw_passwd = smb_xstrdup(from->pw_passwd); - ret->pw_uid = from->pw_uid; - ret->pw_gid = from->pw_gid; - ret->pw_gecos = smb_xstrdup(from->pw_gecos); - ret->pw_dir = smb_xstrdup(from->pw_dir); - ret->pw_shell = smb_xstrdup(from->pw_shell); - return ret; -} + struct passwd *ret = talloc_zero(mem_ctx, struct passwd); -void passwd_free (struct passwd **buf) -{ - if (!*buf) { - DEBUG(0, ("attempted double-free of allocated passwd\n")); - return; - } + if (ret == NULL) + return NULL; - SAFE_FREE((*buf)->pw_name); - SAFE_FREE((*buf)->pw_passwd); - SAFE_FREE((*buf)->pw_gecos); - SAFE_FREE((*buf)->pw_dir); - SAFE_FREE((*buf)->pw_shell); + ret->pw_name = talloc_strdup(ret, from->pw_name); + ret->pw_passwd = talloc_strdup(ret, from->pw_passwd); + ret->pw_uid = from->pw_uid; + ret->pw_gid = from->pw_gid; + ret->pw_gecos = talloc_strdup(ret, from->pw_gecos); + ret->pw_dir = talloc_strdup(ret, from->pw_dir); + ret->pw_shell = talloc_strdup(ret, from->pw_shell); - SAFE_FREE(*buf); + return ret; } -struct passwd *getpwnam_alloc(const char *name) +struct passwd *getpwnam_alloc(TALLOC_CTX *mem_ctx, const char *name) { struct passwd *temp; @@ -66,10 +55,10 @@ struct passwd *getpwnam_alloc(const char *name) return NULL; } - return alloc_copy_passwd(temp); + return alloc_copy_passwd(mem_ctx, temp); } -struct passwd *getpwuid_alloc(uid_t uid) +struct passwd *getpwuid_alloc(TALLOC_CTX *mem_ctx, uid_t uid) { struct passwd *temp; @@ -84,5 +73,5 @@ struct passwd *getpwuid_alloc(uid_t uid) return NULL; } - return alloc_copy_passwd(temp); + return alloc_copy_passwd(mem_ctx, temp); } diff --git a/source4/lib/util/util_str.c b/source4/lib/util/util_str.c index 67e59474fd..9ea6403c52 100644 --- a/source4/lib/util/util_str.c +++ b/source4/lib/util/util_str.c @@ -23,7 +23,6 @@ #include "includes.h" #include "libcli/raw/smb.h" -#include "pstring.h" #include "system/locale.h" /** @@ -237,7 +236,7 @@ _PUBLIC_ void hex_encode(const unsigned char *buff_in, size_t len, char **out_he int i; char *hex_buffer; - *out_hex_buffer = smb_xmalloc((len*2)+1); + *out_hex_buffer = malloc_array_p(char, (len*2)+1); hex_buffer = *out_hex_buffer; for (i = 0; i < len; i++) @@ -261,39 +260,6 @@ _PUBLIC_ char *hex_encode_talloc(TALLOC_CTX *mem_ctx, const unsigned char *buff_ } /** - Set a string value, allocing the space for the string -**/ -static bool string_init(char **dest,const char *src) -{ - if (!src) src = ""; - - (*dest) = strdup(src); - if ((*dest) == NULL) { - DEBUG(0,("Out of memory in string_init\n")); - return false; - } - return true; -} - -/** - Free a string value. -**/ -_PUBLIC_ void string_free(char **s) -{ - if (s) SAFE_FREE(*s); -} - -/** - Set a string value, deallocating any existing space, and allocing the space - for the string -**/ -_PUBLIC_ bool string_set(char **dest, const char *src) -{ - string_free(dest); - return string_init(dest,src); -} - -/** Substitute a string for a pattern in another string. Make sure there is enough room! @@ -305,10 +271,10 @@ _PUBLIC_ bool string_set(char **dest, const char *src) use of len==0 which was for no length checks to be done. **/ -_PUBLIC_ void string_sub(char *s,const char *pattern, const char *insert, size_t len) +_PUBLIC_ void string_sub(char *s, const char *pattern, const char *insert, size_t len) { char *p; - ssize_t ls,lp,li, i; + ssize_t ls, lp, li, i; if (!insert || !pattern || !*pattern || !s) return; @@ -320,7 +286,7 @@ _PUBLIC_ void string_sub(char *s,const char *pattern, const char *insert, size_t if (len == 0) len = ls + 1; /* len is number of *bytes* */ - while (lp <= ls && (p = strstr(s,pattern))) { + while (lp <= ls && (p = strstr(s, pattern))) { if (ls + (li-lp) >= len) { DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", (int)(ls + (li-lp) - len), @@ -351,6 +317,42 @@ _PUBLIC_ void string_sub(char *s,const char *pattern, const char *insert, size_t } } +/** + * Talloc'ed version of string_sub + */ +_PUBLIC_ char *string_sub_talloc(TALLOC_CTX *mem_ctx, const char *s, + const char *pattern, const char *insert) +{ + const char *p; + char *ret; + size_t len, alloc_len; + + if (insert == NULL || pattern == NULL || !*pattern || s == NULL) + return NULL; + + /* determine length needed */ + len = strlen(s); + + for (p = strstr(s, pattern); p != NULL; + p = strstr(p+strlen(pattern), pattern)) { + len += strlen(insert) - strlen(pattern); + } + + alloc_len = MAX(len, strlen(s))+1; + ret = talloc_array(mem_ctx, char, alloc_len); + if (ret == NULL) + return NULL; + strncpy(ret, s, alloc_len); + string_sub(ret, pattern, insert, alloc_len); + + ret = talloc_realloc(mem_ctx, ret, char, len+1); + if (ret == NULL) + return NULL; + + SMB_ASSERT(ret[len] == '\0'); + + return ret; +} /** Similar to string_sub() but allows for any character to be substituted. @@ -457,7 +459,7 @@ _PUBLIC_ const char *str_format_nbt_domain(TALLOC_CTX *mem_ctx, const char *s) if (!s || !*s) { return talloc_strdup(mem_ctx, ""); } - ret = talloc_size(mem_ctx, strlen(s)+2); + ret = talloc_array(mem_ctx, char, strlen(s)+2); if (!ret) { return ret; } @@ -566,7 +568,7 @@ _PUBLIC_ char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib) }; char *ret; - ret = talloc_size(mem_ctx, ARRAY_SIZE(attr_strs)+1); + ret = talloc_array(mem_ctx, char, ARRAY_SIZE(attr_strs)+1); if (!ret) { return NULL; } diff --git a/source4/lib/util/util_strlist.c b/source4/lib/util/util_strlist.c index ab73fb2d15..1f1cc17d00 100644 --- a/source4/lib/util/util_strlist.c +++ b/source4/lib/util/util_strlist.c @@ -19,7 +19,6 @@ */ #include "includes.h" -#include "pstring.h" #include "system/locale.h" /** @@ -152,7 +151,7 @@ _PUBLIC_ char *str_list_join(TALLOC_CTX *mem_ctx, const char **list, char sepera ret = talloc_strdup(mem_ctx, list[0]); for (i = 1; list[i]; i++) { - ret = talloc_asprintf_append(ret, "%c%s", seperator, list[i]); + ret = talloc_asprintf_append_buffer(ret, "%c%s", seperator, list[i]); } return ret; @@ -175,9 +174,9 @@ _PUBLIC_ char *str_list_join_shell(TALLOC_CTX *mem_ctx, const char **list, char for (i = 1; list[i]; i++) { if (strchr(list[i], ' ') || strlen(list[i]) == 0) - ret = talloc_asprintf_append(ret, "%c\"%s\"", sep, list[i]); + ret = talloc_asprintf_append_buffer(ret, "%c\"%s\"", sep, list[i]); else - ret = talloc_asprintf_append(ret, "%c%s", sep, list[i]); + ret = talloc_asprintf_append_buffer(ret, "%c%s", sep, list[i]); } return ret; @@ -300,25 +299,4 @@ _PUBLIC_ bool str_list_check_ci(const char **list, const char *s) return false; } -/** - Check if a string is part of a list. -**/ -_PUBLIC_ bool in_list(const char *s, const char *list, bool casesensitive) -{ - pstring tok; - const char *p=list; - if (!list) - return false; - - while (next_token(&p,tok,LIST_SEP,sizeof(tok))) { - if (casesensitive) { - if (strcmp(tok,s) == 0) - return true; - } else { - if (strcasecmp_m(tok,s) == 0) - return true; - } - } - return false; -} diff --git a/source4/lib/util/util_tdb.c b/source4/lib/util/util_tdb.c index 1112f1587c..d7bddbde01 100644 --- a/source4/lib/util/util_tdb.c +++ b/source4/lib/util/util_tdb.c @@ -22,6 +22,7 @@ #include "includes.h" #include "lib/tdb/include/tdb.h" #include "pstring.h" +#include "lib/util/util_tdb.h" /* these are little tdb utility functions that are meant to make dealing with a tdb database a little less cumbersome in Samba */ @@ -127,7 +128,7 @@ int tdb_store_int32_byblob(struct tdb_context *tdb, const char *keystr, size_t l int32_t v_store; SIVAL(&v_store,0,v); - data.dptr = (void *)&v_store; + data.dptr = (unsigned char *)&v_store; data.dsize = sizeof(int32_t); return tdb_store(tdb, key, data, TDB_REPLACE); @@ -187,7 +188,7 @@ bool tdb_store_uint32_byblob(struct tdb_context *tdb, const char *keystr, size_t bool ret = true; SIVAL(&v_store, 0, value); - data.dptr = (void *)&v_store; + data.dptr = (unsigned char *)&v_store; data.dsize = sizeof(uint32_t); if (tdb_store(tdb, key, data, TDB_REPLACE) == -1) diff --git a/source4/lib/util/xfile.c b/source4/lib/util/xfile.c index 8b90e30868..a016031a77 100644 --- a/source4/lib/util/xfile.c +++ b/source4/lib/util/xfile.c @@ -85,7 +85,7 @@ static int x_allocate_buffer(XFILE *f) { if (f->buf) return 1; if (f->bufsize == 0) return 0; - f->buf = malloc(f->bufsize); + f->buf = (char *)malloc(f->bufsize); if (!f->buf) return 0; f->next = f->buf; return 1; |