summaryrefslogtreecommitdiff
path: root/source4/lib/util
diff options
context:
space:
mode:
Diffstat (limited to 'source4/lib/util')
-rw-r--r--source4/lib/util/dprintf.c39
-rw-r--r--source4/lib/util/ms_fnmatch.c15
-rw-r--r--source4/lib/util/smbrun.c341
-rw-r--r--source4/lib/util/tests/strlist.c25
-rw-r--r--source4/lib/util/util.h1
-rw-r--r--source4/lib/util/util_ldb.c6
-rw-r--r--source4/lib/util/util_strlist.c10
-rw-r--r--source4/lib/util/util_tdb.c17
8 files changed, 71 insertions, 383 deletions
diff --git a/source4/lib/util/dprintf.c b/source4/lib/util/dprintf.c
index 5b3fe4b1ea..308d81b105 100644
--- a/source4/lib/util/dprintf.c
+++ b/source4/lib/util/dprintf.c
@@ -2,6 +2,7 @@
Unix SMB/CIFS implementation.
display print functions
Copyright (C) Andrew Tridgell 2001
+ 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
@@ -32,13 +33,26 @@
#include "includes.h"
#include "system/locale.h"
+#include "param/param.h"
+
+static smb_iconv_t display_cd = (smb_iconv_t)-1;
+
+void d_set_iconv(smb_iconv_t cd)
+{
+ display_cd = cd;
+}
_PUBLIC_ int d_vfprintf(FILE *f, const char *format, va_list ap) _PRINTF_ATTRIBUTE(2,0)
{
char *p, *p2;
- int ret, maxlen, clen;
+ int ret, clen;
va_list ap2;
+ /* If there's nothing to convert, take a shortcut */
+ if (display_cd == (smb_iconv_t)-1) {
+ return vfprintf(f, format, ap);
+ }
+
/* do any message translations */
va_copy(ap2, ap);
ret = vasprintf(&p, format, ap2);
@@ -46,16 +60,7 @@ _PUBLIC_ int d_vfprintf(FILE *f, const char *format, va_list ap) _PRINTF_ATTRIBU
if (ret <= 0) return ret;
- /* now we have the string in unix format, convert it to the display
- charset, but beware of it growing */
- maxlen = ret*2;
-again:
- p2 = (char *)malloc(maxlen);
- if (!p2) {
- SAFE_FREE(p);
- return -1;
- }
- clen = convert_string(global_smb_iconv_convenience, CH_UNIX, CH_DISPLAY, p, ret, p2, maxlen);
+ clen = convert_string_talloc_descriptor(NULL, display_cd, p, ret, (void **)&p2);
if (clen == -1) {
/* the string can't be converted - do the best we can,
filling in non-printing chars with '?' */
@@ -68,22 +73,13 @@ again:
}
}
SAFE_FREE(p);
- SAFE_FREE(p2);
return ret;
}
-
- if (clen >= maxlen) {
- /* it didn't fit - try a larger buffer */
- maxlen *= 2;
- SAFE_FREE(p2);
- goto again;
- }
-
/* good, its converted OK */
SAFE_FREE(p);
ret = fwrite(p2, 1, clen, f);
- SAFE_FREE(p2);
+ talloc_free(p2);
return ret;
}
@@ -112,3 +108,4 @@ _PUBLIC_ int d_printf(const char *format, ...) _PRINTF_ATTRIBUTE(1,2)
return ret;
}
+
diff --git a/source4/lib/util/ms_fnmatch.c b/source4/lib/util/ms_fnmatch.c
index e1bf6f94c5..1fb57b07a4 100644
--- a/source4/lib/util/ms_fnmatch.c
+++ b/source4/lib/util/ms_fnmatch.c
@@ -29,6 +29,7 @@
*/
#include "includes.h"
+#include "param/param.h"
static int null_match(const char *p)
{
@@ -64,7 +65,7 @@ static int ms_fnmatch_core(const char *p, const char *n,
int i;
size_t size, size_n;
- while ((c = next_codepoint(global_smb_iconv_convenience, p, &size))) {
+ while ((c = next_codepoint(lp_iconv_convenience(global_loadparm), p, &size))) {
p += size;
switch (c) {
@@ -74,7 +75,7 @@ static int ms_fnmatch_core(const char *p, const char *n,
return null_match(p);
}
for (i=0; n[i]; i += size_n) {
- next_codepoint(global_smb_iconv_convenience, n+i, &size_n);
+ next_codepoint(lp_iconv_convenience(global_loadparm), n+i, &size_n);
if (ms_fnmatch_core(p, n+i, max_n+1, ldot) == 0) {
return 0;
}
@@ -93,7 +94,7 @@ static int ms_fnmatch_core(const char *p, const char *n,
return -1;
}
for (i=0; n[i]; i += size_n) {
- next_codepoint(global_smb_iconv_convenience, n+i, &size_n);
+ next_codepoint(lp_iconv_convenience(global_loadparm), n+i, &size_n);
if (ms_fnmatch_core(p, n+i, max_n+1, ldot) == 0) return 0;
if (n+i == ldot) {
if (ms_fnmatch_core(p, n+i+size_n, max_n+1, ldot) == 0) return 0;
@@ -109,7 +110,7 @@ static int ms_fnmatch_core(const char *p, const char *n,
if (! *n) {
return -1;
}
- next_codepoint(global_smb_iconv_convenience, n, &size_n);
+ next_codepoint(lp_iconv_convenience(global_loadparm), n, &size_n);
n += size_n;
break;
@@ -123,7 +124,7 @@ static int ms_fnmatch_core(const char *p, const char *n,
break;
}
if (! *n) return null_match(p);
- next_codepoint(global_smb_iconv_convenience, n, &size_n);
+ next_codepoint(lp_iconv_convenience(global_loadparm), n, &size_n);
n += size_n;
break;
@@ -133,12 +134,12 @@ static int ms_fnmatch_core(const char *p, const char *n,
return 0;
}
if (*n != '.') return -1;
- next_codepoint(global_smb_iconv_convenience, n, &size_n);
+ next_codepoint(lp_iconv_convenience(global_loadparm), n, &size_n);
n += size_n;
break;
default:
- c2 = next_codepoint(global_smb_iconv_convenience, n, &size_n);
+ c2 = next_codepoint(lp_iconv_convenience(global_loadparm), n, &size_n);
if (c != c2 && codepoint_cmpi(c, c2) != 0) {
return -1;
}
diff --git a/source4/lib/util/smbrun.c b/source4/lib/util/smbrun.c
deleted file mode 100644
index 26330ab992..0000000000
--- a/source4/lib/util/smbrun.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- run a command as a specified user
- Copyright (C) Andrew Tridgell 1992-1998
-
- 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"
-
-/* need to move this from here!! need some sleep ... */
-struct current_user current_user;
-
-/****************************************************************************
-This is a utility function of smbrun().
-****************************************************************************/
-
-static int setup_out_fd(void)
-{
- int fd;
- TALLOC_CTX *ctx = talloc_stackframe();
- char *path = NULL;
-
- path = talloc_asprintf(ctx,
- "%s/smb.XXXXXX",
- tmpdir());
- if (!path) {
- TALLOC_FREE(ctx);
- errno = ENOMEM;
- return -1;
- }
-
- /* now create the file */
- fd = smb_mkstemp(path);
-
- if (fd == -1) {
- DEBUG(0,("setup_out_fd: Failed to create file %s. (%s)\n",
- path, strerror(errno) ));
- TALLOC_FREE(ctx);
- return -1;
- }
-
- DEBUG(10,("setup_out_fd: Created tmp file %s\n", path ));
-
- /* Ensure file only kept around by open fd. */
- unlink(path);
- TALLOC_FREE(ctx);
- return fd;
-}
-
-/****************************************************************************
-run a command being careful about uid/gid handling and putting the output in
-outfd (or discard it if outfd is NULL).
-****************************************************************************/
-
-static int smbrun_internal(const char *cmd, int *outfd, BOOL sanitize)
-{
- pid_t pid;
- uid_t uid = current_user.ut.uid;
- gid_t gid = current_user.ut.gid;
-
- /*
- * Lose any elevated privileges.
- */
- drop_effective_capability(KERNEL_OPLOCK_CAPABILITY);
- drop_effective_capability(DMAPI_ACCESS_CAPABILITY);
-
- /* point our stdout at the file we want output to go into */
-
- if (outfd && ((*outfd = setup_out_fd()) == -1)) {
- return -1;
- }
-
- /* in this method we will exec /bin/sh with the correct
- arguments, after first setting stdout to point at the file */
-
- /*
- * We need to temporarily stop CatchChild from eating
- * SIGCLD signals as it also eats the exit status code. JRA.
- */
-
- CatchChildLeaveStatus();
-
- if ((pid=sys_fork()) < 0) {
- DEBUG(0,("smbrun: fork failed with error %s\n", strerror(errno) ));
- CatchChild();
- if (outfd) {
- close(*outfd);
- *outfd = -1;
- }
- return errno;
- }
-
- if (pid) {
- /*
- * Parent.
- */
- int status=0;
- pid_t wpid;
-
-
- /* the parent just waits for the child to exit */
- while((wpid = sys_waitpid(pid,&status,0)) < 0) {
- if(errno == EINTR) {
- errno = 0;
- continue;
- }
- break;
- }
-
- CatchChild();
-
- if (wpid != pid) {
- DEBUG(2,("waitpid(%d) : %s\n",(int)pid,strerror(errno)));
- if (outfd) {
- close(*outfd);
- *outfd = -1;
- }
- return -1;
- }
-
- /* Reset the seek pointer. */
- if (outfd) {
- sys_lseek(*outfd, 0, SEEK_SET);
- }
-
-#if defined(WIFEXITED) && defined(WEXITSTATUS)
- if (WIFEXITED(status)) {
- return WEXITSTATUS(status);
- }
-#endif
-
- return status;
- }
-
- CatchChild();
-
- /* we are in the child. we exec /bin/sh to do the work for us. we
- don't directly exec the command we want because it may be a
- pipeline or anything else the config file specifies */
-
- /* point our stdout at the file we want output to go into */
- if (outfd) {
- close(1);
- if (sys_dup2(*outfd,1) != 1) {
- DEBUG(2,("Failed to create stdout file descriptor\n"));
- close(*outfd);
- exit(80);
- }
- }
-
- /* now completely lose our privileges. This is a fairly paranoid
- way of doing it, but it does work on all systems that I know of */
-
- become_user_permanently(uid, gid);
-
- if (getuid() != uid || geteuid() != uid ||
- getgid() != gid || getegid() != gid) {
- /* we failed to lose our privileges - do not execute
- the command */
- exit(81); /* we can't print stuff at this stage,
- instead use exit codes for debugging */
- }
-
-#ifndef __INSURE__
- /* close all other file descriptors, leaving only 0, 1 and 2. 0 and
- 2 point to /dev/null from the startup code */
- {
- int fd;
- for (fd=3;fd<256;fd++) close(fd);
- }
-#endif
-
- {
- const char *newcmd = sanitize ? escape_shell_string(cmd) : cmd;
- if (!newcmd) {
- exit(82);
- }
- execl("/bin/sh","sh","-c",newcmd,NULL);
- }
-
- /* not reached */
- exit(83);
- return 1;
-}
-
-/****************************************************************************
- Use only in known safe shell calls (printing).
-****************************************************************************/
-
-int smbrun_no_sanitize(const char *cmd, int *outfd)
-{
- return smbrun_internal(cmd, outfd, False);
-}
-
-/****************************************************************************
- By default this now sanitizes shell expansion.
-****************************************************************************/
-
-int smbrun(const char *cmd, int *outfd)
-{
- return smbrun_internal(cmd, outfd, True);
-}
-
-/****************************************************************************
-run a command being careful about uid/gid handling and putting the output in
-outfd (or discard it if outfd is NULL).
-sends the provided secret to the child stdin.
-****************************************************************************/
-
-int smbrunsecret(const char *cmd, const char *secret)
-{
- pid_t pid;
- uid_t uid = current_user.ut.uid;
- gid_t gid = current_user.ut.gid;
- int ifd[2];
-
- /*
- * Lose any elevated privileges.
- */
- drop_effective_capability(KERNEL_OPLOCK_CAPABILITY);
- drop_effective_capability(DMAPI_ACCESS_CAPABILITY);
-
- /* build up an input pipe */
- if(pipe(ifd)) {
- return -1;
- }
-
- /* in this method we will exec /bin/sh with the correct
- arguments, after first setting stdout to point at the file */
-
- /*
- * We need to temporarily stop CatchChild from eating
- * SIGCLD signals as it also eats the exit status code. JRA.
- */
-
- CatchChildLeaveStatus();
-
- if ((pid=sys_fork()) < 0) {
- DEBUG(0, ("smbrunsecret: fork failed with error %s\n", strerror(errno)));
- CatchChild();
- return errno;
- }
-
- if (pid) {
- /*
- * Parent.
- */
- int status = 0;
- pid_t wpid;
- size_t towrite;
- ssize_t wrote;
-
- close(ifd[0]);
- /* send the secret */
- towrite = strlen(secret);
- wrote = write(ifd[1], secret, towrite);
- if ( wrote != towrite ) {
- DEBUG(0,("smbrunsecret: wrote %ld of %lu bytes\n",(long)wrote,(unsigned long)towrite));
- }
- fsync(ifd[1]);
- close(ifd[1]);
-
- /* the parent just waits for the child to exit */
- while((wpid = sys_waitpid(pid, &status, 0)) < 0) {
- if(errno == EINTR) {
- errno = 0;
- continue;
- }
- break;
- }
-
- CatchChild();
-
- if (wpid != pid) {
- DEBUG(2, ("waitpid(%d) : %s\n", (int)pid, strerror(errno)));
- return -1;
- }
-
-#if defined(WIFEXITED) && defined(WEXITSTATUS)
- if (WIFEXITED(status)) {
- return WEXITSTATUS(status);
- }
-#endif
-
- return status;
- }
-
- CatchChild();
-
- /* we are in the child. we exec /bin/sh to do the work for us. we
- don't directly exec the command we want because it may be a
- pipeline or anything else the config file specifies */
-
- close(ifd[1]);
- close(0);
- if (sys_dup2(ifd[0], 0) != 0) {
- DEBUG(2,("Failed to create stdin file descriptor\n"));
- close(ifd[0]);
- exit(80);
- }
-
- /* now completely lose our privileges. This is a fairly paranoid
- way of doing it, but it does work on all systems that I know of */
-
- become_user_permanently(uid, gid);
-
- if (getuid() != uid || geteuid() != uid ||
- getgid() != gid || getegid() != gid) {
- /* we failed to lose our privileges - do not execute
- the command */
- exit(81); /* we can't print stuff at this stage,
- instead use exit codes for debugging */
- }
-
-#ifndef __INSURE__
- /* close all other file descriptors, leaving only 0, 1 and 2. 0 and
- 2 point to /dev/null from the startup code */
- {
- int fd;
- for (fd = 3; fd < 256; fd++) close(fd);
- }
-#endif
-
- execl("/bin/sh", "sh", "-c", cmd, NULL);
-
- /* not reached */
- exit(82);
- return 1;
-}
diff --git a/source4/lib/util/tests/strlist.c b/source4/lib/util/tests/strlist.c
index 437d9d741a..3ecb982e24 100644
--- a/source4/lib/util/tests/strlist.c
+++ b/source4/lib/util/tests/strlist.c
@@ -64,6 +64,29 @@ static bool test_lists_shell(struct torture_context *tctx,
return true;
}
+static bool test_list_copy(struct torture_context *tctx)
+{
+ const char **result;
+ const char *list[] = { "foo", "bar", NULL };
+ const char *empty_list[] = { NULL };
+ const char **null_list = NULL;
+
+ result = str_list_copy(tctx, list);
+ torture_assert_int_equal(tctx, str_list_length(result), 2, "list length");
+ torture_assert_str_equal(tctx, result[0], "foo", "element 0");
+ torture_assert_str_equal(tctx, result[1], "bar", "element 1");
+ torture_assert_str_equal(tctx, result[2], NULL, "element 2");
+
+ result = str_list_copy(tctx, empty_list);
+ torture_assert_int_equal(tctx, str_list_length(result), 0, "list length");
+ torture_assert_str_equal(tctx, result[0], NULL, "element 0");
+
+ result = str_list_copy(tctx, null_list);
+ torture_assert(tctx, result == NULL, "result NULL");
+
+ return true;
+}
+
struct torture_suite *torture_local_util_strlist(TALLOC_CTX *mem_ctx)
{
struct torture_suite *suite = torture_suite_create(mem_ctx, "STRLIST");
@@ -75,5 +98,7 @@ struct torture_suite *torture_local_util_strlist(TALLOC_CTX *mem_ctx)
&test_lists_shell_strings[i]);
}
+ torture_suite_add_simple_test(suite, "list_copy", test_list_copy);
+
return suite;
}
diff --git a/source4/lib/util/util.h b/source4/lib/util/util.h
index f3adbb3333..9e106052f2 100644
--- a/source4/lib/util/util.h
+++ b/source4/lib/util/util.h
@@ -262,6 +262,7 @@ _PUBLIC_ char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len);
/* The following definitions come from lib/util/dprintf.c */
+_PUBLIC_ void d_set_iconv(smb_iconv_t);
_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);
diff --git a/source4/lib/util/util_ldb.c b/source4/lib/util/util_ldb.c
index ba8443c236..a8719af190 100644
--- a/source4/lib/util/util_ldb.c
+++ b/source4/lib/util/util_ldb.c
@@ -23,16 +23,16 @@
#include "includes.h"
#include "lib/ldb/include/ldb.h"
#include "lib/ldb/include/ldb_errors.h"
-
+#include "lib/util/util_ldb.h"
/*
search the sam for the specified attributes - va_list variant
*/
-int gendb_search_v(struct ldb_context *ldb,
+int gendb_search_v(struct ldb_context *ldb,
TALLOC_CTX *mem_ctx,
struct ldb_dn *basedn,
struct ldb_message ***msgs,
const char * const *attrs,
- const char *format,
+ const char *format,
va_list ap) _PRINTF_ATTRIBUTE(6,0)
{
enum ldb_scope scope = LDB_SCOPE_SUBTREE;
diff --git a/source4/lib/util/util_strlist.c b/source4/lib/util/util_strlist.c
index 1f1cc17d00..30de4b962d 100644
--- a/source4/lib/util/util_strlist.c
+++ b/source4/lib/util/util_strlist.c
@@ -199,8 +199,14 @@ _PUBLIC_ size_t str_list_length(const char **list)
_PUBLIC_ const char **str_list_copy(TALLOC_CTX *mem_ctx, const char **list)
{
int i;
- const char **ret = talloc_array(mem_ctx, const char *, str_list_length(list)+1);
- if (ret == NULL) return NULL;
+ const char **ret;
+
+ if (list == NULL)
+ return NULL;
+
+ ret = talloc_array(mem_ctx, const char *, str_list_length(list)+1);
+ if (ret == NULL)
+ return NULL;
for (i=0;list && list[i];i++) {
ret[i] = talloc_strdup(ret, list[i]);
diff --git a/source4/lib/util/util_tdb.c b/source4/lib/util/util_tdb.c
index d7bddbde01..77ad4eb617 100644
--- a/source4/lib/util/util_tdb.c
+++ b/source4/lib/util/util_tdb.c
@@ -445,7 +445,7 @@ int tdb_unpack(TDB_CONTEXT *tdb, char *buf, int bufsize, const char *fmt, ...)
int len;
int *i;
void **p;
- char *s, **b;
+ char *s, **b, **ps;
char c;
char *buf0 = buf;
const char *fmt0 = fmt;
@@ -453,7 +453,7 @@ int tdb_unpack(TDB_CONTEXT *tdb, char *buf, int bufsize, const char *fmt, ...)
tdb_log_func log_fn = tdb_log_fn(tdb);
va_start(ap, fmt);
-
+
while (*fmt) {
switch ((c=*fmt++)) {
case 'b':
@@ -485,11 +485,10 @@ int tdb_unpack(TDB_CONTEXT *tdb, char *buf, int bufsize, const char *fmt, ...)
*p = (void *)IVAL(buf, 0);
break;
case 'P':
- s = va_arg(ap,char *);
- len = strlen(buf) + 1;
- if (bufsize < len || len > sizeof(pstring))
- goto no_space;
- memcpy(s, buf, len);
+ /* Return a malloc'ed string. */
+ ps = va_arg(ap,char ** );
+ len = strlen((const char *)buf) + 1;
+ *ps = strdup((const char *)buf);
break;
case 'f':
s = va_arg(ap,char *);
@@ -518,7 +517,7 @@ int tdb_unpack(TDB_CONTEXT *tdb, char *buf, int bufsize, const char *fmt, ...)
memcpy(*b, buf+4, *i);
break;
default:
- log_fn(tdb, 0, "Unknown tdb_unpack format %c in %s\n",
+ log_fn(tdb, 0, "Unknown tdb_unpack format %c in %s\n",
c, fmt);
len = 0;
@@ -531,7 +530,7 @@ int tdb_unpack(TDB_CONTEXT *tdb, char *buf, int bufsize, const char *fmt, ...)
va_end(ap);
- log_fn(tdb, 18, "tdb_unpack(%s, %d) -> %d\n",
+ log_fn(tdb, 18, "tdb_unpack(%s, %d) -> %d\n",
fmt0, bufsize0, (int)PTR_DIFF(buf, buf0));
return PTR_DIFF(buf, buf0);