summaryrefslogtreecommitdiffstats
path: root/source/lib
diff options
context:
space:
mode:
Diffstat (limited to 'source/lib')
-rw-r--r--source/lib/access.c12
-rw-r--r--source/lib/charcnv.c174
-rw-r--r--source/lib/debug.c21
-rw-r--r--source/lib/interface.c9
-rw-r--r--source/lib/kanji.c349
-rw-r--r--source/lib/messages.c128
-rw-r--r--source/lib/pidfile.c6
-rw-r--r--source/lib/replace.c42
-rw-r--r--source/lib/snprintf.c34
-rw-r--r--source/lib/substitute.c17
-rw-r--r--source/lib/sysacls.c4
-rw-r--r--source/lib/system.c134
-rw-r--r--source/lib/talloc.c354
-rw-r--r--source/lib/username.c16
-rw-r--r--source/lib/util.c206
-rw-r--r--source/lib/util_file.c5
-rw-r--r--source/lib/util_seaccess.c27
-rw-r--r--source/lib/util_sec.c2
-rw-r--r--source/lib/util_sid.c163
-rw-r--r--source/lib/util_sock.c361
-rw-r--r--source/lib/util_str.c95
-rw-r--r--source/lib/util_unistr.c46
-rw-r--r--source/lib/wins_srv.c6
23 files changed, 1669 insertions, 542 deletions
diff --git a/source/lib/access.c b/source/lib/access.c
index d61915f0b24..73b4d57e706 100644
--- a/source/lib/access.c
+++ b/source/lib/access.c
@@ -15,6 +15,8 @@ static char *sep = ", \t";
#define FAIL (-1)
+#define ALLONES ((uint32)0xFFFFFFFF)
+
/* masked_match - match address against netnumber/netmask */
static int masked_match(char *tok, char *slash, char *s)
{
@@ -27,8 +29,14 @@ static int masked_match(char *tok, char *slash, char *s)
*slash = 0;
net = interpret_addr(tok);
*slash = '/';
- if (net == INADDR_NONE ||
- (mask = interpret_addr(slash + 1)) == INADDR_NONE) {
+
+ if (strlen(slash + 1) > 2) {
+ mask = interpret_addr(slash + 1);
+ } else {
+ mask = (uint32)((ALLONES >> atoi(slash + 1)) ^ ALLONES);
+ }
+
+ if (net == INADDR_NONE || mask == INADDR_NONE) {
DEBUG(0,("access: bad net/mask access control: %s\n", tok));
return (False);
}
diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c
index 0462668ff84..2affa6a9e06 100644
--- a/source/lib/charcnv.c
+++ b/source/lib/charcnv.c
@@ -161,11 +161,21 @@ update_map("\370\375\371\205\372\243\373\373\374\201\375\354\376\356\377\372");
/* Init for russian language (iso8859-5) */
/* Added by Max Khon <max@iclub.nsu.ru> */
-
-static void init_iso8859_5(void)
+/* 1125 mapping added by Alexander Bokovoy <a.bokovoy@sam-solutions.net> */
+static void init_iso8859_5(int codepage)
{
setupmaps();
+ if (codepage == 1125) {
+/* MSDOS Code Page 1125 -> ISO8859-5 */
+update_map ("\360\374\361\361\340\340\341\341\320\240\342\342\321\241\300\220");
+update_map ("\364\365\343\343\322\242\301\221\260\200\344\344\323\243\302\222");
+update_map ("\261\201\366\367\241\360\345\345\324\244\303\223\262\202\367\371");
+update_map ("\346\346\325\245\304\224\263\203\347\347\326\246\305\225\264\204");
+update_map ("\244\364\350\350\327\247\306\226\265\205\351\351\330\250\307\227");
+update_map ("\266\206\246\366\331\251\310\230\267\207\247\370\311\231\270\210");
+update_map ("\271\211");
+ } else {
/* MSDOS Code Page 866 -> ISO8859-5 */
update_map("\260\200\261\201\262\202\263\203\264\204\265\205\266\206\267\207");
update_map("\270\210\271\211\272\212\273\213\274\214\275\215\276\216\277\217");
@@ -177,6 +187,7 @@ update_map("\340\340\341\341\342\342\343\343\344\344\345\345\346\346\347\347");
update_map("\350\350\351\351\352\352\353\353\354\354\355\355\356\356\357\357");
update_map("\241\360\361\361\244\362\364\363\247\364\367\365\256\366\376\367");
update_map("\360\374\240\377");
+ }
}
/* Added by Antonios Kavarnos (Antonios.Kavarnos@softlab.ece.ntua.gr */
@@ -201,6 +212,20 @@ update_map("\266\352");
update_map("\270\353\271\354\272\355\274\356\276\357\277\360");
}
+/* Added by Yedidyah Bar-David (didi@tau.ac.il) */
+
+static void init_iso8859_8(void)
+{
+ setupmaps();
+
+/* MSDOS Code Page 862 -> ISO-8859-8 (Hebrew) */
+
+update_map("\340\200\341\201\342\202\343\203\344\204\345\205\346\206\347\207");
+update_map("\350\210\351\211\352\212\353\213\354\214\355\215\356\216\357\217");
+update_map("\360\220\361\221\362\222\363\223\364\224\365\225\366\226\367\227");
+update_map("\370\230\371\231\372\232");
+}
+
/* Added by Deniz Akkus (akkus@alum.mit.edu) */
static void init_iso8859_9(void)
@@ -272,12 +297,12 @@ update_map("\370\234\371\233\372\207\373\230\374\235\375\231\376\227\377\232");
/* Init for Bulgarian, Belarussian, and variants of Russian and Ukrainian locales */
/* Patch from Alexander Bokovoy. */
-static void init_1251(void)
+static void init_1251(int codepage)
{
setupmaps();
+ if (codepage == 866) {
/* MSDOS Code Page 866 -> 1251 */
-
update_map ("\240\377\241\366\242\367\244\375");
update_map ("\250\360\252\362\257\364");
update_map ("\260\370\267\372");
@@ -290,9 +315,58 @@ update_map ("\340\240\341\241\342\242\343\243\344\244\345\245\346\246\347\247");
update_map ("\350\250\351\251\352\252\353\253\354\254\355\255\356\256\357\257");
update_map ("\360\340\361\341\362\342\363\343\364\344\365\345\366\346\367\347");
update_map ("\370\350\371\351\372\352\373\353\374\354\375\355\376\356\377\357");
+ } else {
+/* MSDOS Code Page 1125 (Ukranian) -> 1251 */
+update_map ("\271\374\270\361\360\340\361\341\340\240\362\342\341\241\320\220");
+update_map ("\272\365\363\343\342\242\321\221\300\200\364\344\343\243\322\222");
+update_map ("\301\201\263\367\250\360\365\345\344\244\323\223\302\202\277\371");
+update_map ("\366\346\345\245\324\224\303\203\367\347\346\246\325\225\304\204");
+update_map ("\252\364\370\350\347\247\326\226\305\205\371\351\350\250\327\227");
+update_map ("\306\206\262\366\351\251\330\230\307\207\257\370\331\231\310\210");
+update_map ("\311\211\245\362\264\363");
+ }
}
+/* Init for ukrainian language (koi8-u) */
+/* Added by Oleg Deribas <older@iname.com> */
+
+static void init_koi8_u(int codepage)
+{
+ setupmaps();
+
+ if (codepage == 866) {
+ /* MSDOS Code Page 866 -> KOI8-U */
+ update_map("\x80\xC4\x81\xB3\x82\xDA\x83\xBF\x84\xC0\x85\xD9\x86\xC3\x87\xB4\x88\xC2");
+ update_map("\x89\xC1\x8A\xC5\x8B\xDF\x8C\xDC\x8D\xDB\x8E\xDD\x8F\xDE\x90\xB0\x91\xB1");
+ update_map("\x92\xB2\x94\xFE\x95\xF9\x96\xFB\x9A\xFF\x9C\xF8\x9E\xFA\xA0\xCD\xA1\xBA");
+ update_map("\xA2\xD5\xA3\xF1\xA4\xF3\xA5\xC9\xA7\xF5\xA8\xBB\xA9\xD4\xAA\xD3\xAB\xC8");
+ update_map("\xAC\xBE\xAE\xBC\xAF\xC6\xB0\xC7\xB1\xCC\xB2\xB5\xB3\xF0\xB4\xF2\xB5\xB9");
+ update_map("\xB7\xF4\xB8\xCB\xB9\xCF\xBA\xD0\xBB\xCA\xBC\xD8\xBE\xCE\xC0\xEE\xC1\xA0");
+ update_map("\xC2\xA1\xC3\xE6\xC4\xA4\xC5\xA5\xC6\xE4\xC7\xA3\xC8\xE5\xC9\xA8\xCA\xA9");
+ update_map("\xCB\xAA\xCC\xAB\xCD\xAC\xCE\xAD\xCF\xAE\xD0\xAF\xD1\xEF\xD2\xE0\xD3\xE1");
+ update_map("\xD4\xE2\xD5\xE3\xD6\xA6\xD7\xA2\xD8\xEC\xD9\xEB\xDA\xA7\xDB\xE8\xDC\xED");
+ update_map("\xDD\xE9\xDE\xE7\xDF\xEA\xE0\x9E\xE1\x80\xE2\x81\xE3\x96\xE4\x84\xE5\x85");
+ update_map("\xE6\x94\xE7\x83\xE8\x95\xE9\x88\xEA\x89\xEB\x8A\xEC\x8B\xED\x8C\xEE\x8D");
+ update_map("\xEF\x8E\xF0\x8F\xF1\x9F\xF2\x90\xF3\x91\xF4\x92\xF5\x93\xF6\x86\xF7\x82");
+ update_map("\xF8\x9C\xF9\x9B\xFA\x87\xFB\x98\xFC\x9D\xFD\x99\xFE\x97\xFF\x9A");
+ } else {
+ /* MSDOS Code Page 1125 -> KOI8-U */
+ update_map("\x80\xC4\x81\xB3\x82\xDA\x83\xBF\x84\xC0\x85\xD9\x86\xC3\x87\xB4\x88\xC2\x89\xC1");
+ update_map("\x8A\xC5\x8B\xDF\x8C\xDC\x8D\xDB\x8E\xDD\x8F\xDE\x90\xB0\x91\xB1\x92\xB2\x94\xFE");
+ update_map("\x96\xFB\x9A\xFF\x9E\xFA\xA0\xCD\xA1\xBA\xA2\xD5\xA3\xF1\xA4\xF5\xA5\xC9\xA6\xF7");
+ update_map("\xA7\xF9\xA8\xBB\xA9\xD4\xAA\xD3\xAB\xC8\xAC\xBE\xAD\xF3\xAE\xBC\xAF\xC6\xB0\xC7");
+ update_map("\xB1\xCC\xB2\xB5\xB3\xF0\xB4\xF4\xB5\xB9\xB6\xF6\xB7\xF8\xB8\xCB\xB9\xCF\xBA\xD0");
+ update_map("\xBB\xCA\xBC\xD8\xBD\xF2\xBE\xCE\xC0\xEE\xC1\xA0\xC2\xA1\xC3\xE6\xC4\xA4\xC5\xA5");
+ update_map("\xC6\xE4\xC7\xA3\xC8\xE5\xC9\xA8\xCA\xA9\xCB\xAA\xCC\xAB\xCD\xAC\xCE\xAD\xCF\xAE");
+ update_map("\xD0\xAF\xD1\xEF\xD2\xE0\xD3\xE1\xD4\xE2\xD5\xE3\xD6\xA6\xD7\xA2\xD8\xEC\xD9\xEB");
+ update_map("\xDA\xA7\xDB\xE8\xDC\xED\xDD\xE9\xDE\xE7\xDF\xEA\xE0\x9E\xE1\x80\xE2\x81\xE3\x96");
+ update_map("\xE4\x84\xE5\x85\xE6\x94\xE7\x83\xE8\x95\xE9\x88\xEA\x89\xEB\x8A\xEC\x8B\xED\x8C");
+ update_map("\xEE\x8D\xEF\x8E\xF0\x8F\xF1\x9F\xF2\x90\xF3\x91\xF4\x92\xF5\x93\xF6\x86\xF7\x82");
+ update_map("\xF8\x9C\xF9\x9B\xFA\x87\xFB\x98\xFC\x9D\xFD\x99\xFE\x97\xFF\x9A");
+ }
+}
+
/* Init for ROMAN-8 (HP-UX) */
static void init_roman8(void) {
@@ -317,47 +391,61 @@ update_map("\370\253\371\246\372\247\373\256\374\376\375\257\376\361");
/*
* Convert unix to dos
*/
-char *unix2dos_format(char *str,BOOL overwrite)
+
+char *unix2dos_format_static(const char *str)
+{
+ const char *p;
+ char *dp;
+
+ if (!mapsinited)
+ initmaps();
+
+ for (p = str, dp = cvtbuf;*p && (dp - cvtbuf < sizeof(cvtbuf) - 1); p++,dp++)
+ *dp = unix2dos[(unsigned char)*p];
+ *dp = 0;
+ return cvtbuf;
+}
+
+char *unix2dos_format(char *str)
{
- char *p;
- char *dp;
-
- if (!mapsinited)
- initmaps();
-
- if (overwrite) {
- for (p = str; *p; p++)
- *p = unix2dos[(unsigned char)*p];
- return str;
- } else {
- for (p = str, dp = cvtbuf;*p && (dp - cvtbuf < sizeof(cvtbuf) - 1); p++,dp++)
- *dp = unix2dos[(unsigned char)*p];
- *dp = 0;
- return cvtbuf;
- }
+ char *p;
+
+ if (!mapsinited)
+ initmaps();
+
+ for (p = str; *p; p++)
+ *p = unix2dos[(unsigned char)*p];
+ return str;
}
/*
* Convert dos to unix
*/
-char *dos2unix_format(char *str, BOOL overwrite)
+
+char *dos2unix_format_static(const char *str)
+{
+ const char *p;
+ char *dp;
+
+ if (!mapsinited)
+ initmaps();
+
+ for (p = str, dp = cvtbuf;*p && (dp - cvtbuf < sizeof(cvtbuf) - 1); p++,dp++)
+ *dp = dos2unix[(unsigned char)*p];
+ *dp = 0;
+ return cvtbuf;
+}
+
+char *dos2unix_format(char *str)
{
- char *p;
- char *dp;
-
- if (!mapsinited)
- initmaps();
-
- if (overwrite) {
- for (p = str; *p; p++)
- *p = dos2unix[(unsigned char)*p];
- return str;
- } else {
- for (p = str, dp = cvtbuf;*p && (dp - cvtbuf < sizeof(cvtbuf) - 1); p++,dp++)
- *dp = dos2unix[(unsigned char)*p];
- *dp = 0;
- return cvtbuf;
- }
+ char *p;
+
+ if (!mapsinited)
+ initmaps();
+
+ for (p = str; *p; p++)
+ *p = dos2unix[(unsigned char)*p];
+ return str;
}
@@ -371,7 +459,9 @@ void interpret_character_set(char *str, int codepage)
} else if (strequal (str, "iso8859-2")) {
init_iso8859_2();
} else if (strequal (str, "iso8859-5")) {
- init_iso8859_5();
+ init_iso8859_5(codepage);
+ } else if (strequal (str, "iso8859-8")) {
+ init_iso8859_8();
} else if (strequal (str, "iso8859-7")) {
init_iso8859_7();
} else if (strequal (str, "iso8859-9")) {
@@ -382,8 +472,12 @@ void interpret_character_set(char *str, int codepage)
init_iso8859_15(codepage);
} else if (strequal (str, "koi8-r")) {
init_koi8_r();
+ } else if (strequal (str, "koi8-u")) {
+ init_koi8_u(codepage);
+ } else if (strequal (str, "1251u")) {
+ init_1251(1125);
} else if (strequal (str, "1251")) {
- init_1251();
+ init_1251(866);
} else if (strequal (str, "roman8")) {
init_roman8();
} else {
diff --git a/source/lib/debug.c b/source/lib/debug.c
index d3ba8f9c370..3731b3656fa 100644
--- a/source/lib/debug.c
+++ b/source/lib/debug.c
@@ -86,7 +86,7 @@ BOOL append_log = False;
int DEBUGLEVEL_CLASS[DBGC_LAST];
int DEBUGLEVEL = DEBUGLEVEL_CLASS;
BOOL AllowDebugChange = True;
-
+int parsed_debuglevel_class[DBGC_LAST];
/* -------------------------------------------------------------------------- **
* Internal variables.
@@ -214,8 +214,6 @@ BOOL debug_parse_levels(char *params_str)
char *params[DBGC_LAST];
int debuglevel_class[DBGC_LAST];
- if (AllowDebugChange == False)
- return True;
ZERO_ARRAY(params);
ZERO_ARRAY(debuglevel_class);
@@ -228,8 +226,19 @@ BOOL debug_parse_levels(char *params_str)
else
return False;
+ if (AllowDebugChange == False) {
+ int old_debuglevel_class[DBGC_LAST];
+
+ /* save current debug level */
+ memcpy(old_debuglevel_class, DEBUGLEVEL_CLASS, sizeof(DEBUGLEVEL_CLASS));
+ if (debug_parse_params(params, debuglevel_class))
+ debug_message(0, getpid(), (void*)debuglevel_class, sizeof(debuglevel_class));
+ memcpy(parsed_debuglevel_class, DEBUGLEVEL_CLASS, sizeof(DEBUGLEVEL_CLASS));
+ memcpy(DEBUGLEVEL_CLASS, old_debuglevel_class, sizeof(old_debuglevel_class));
+ return True;
+ }
if (debug_parse_params(params, debuglevel_class)) {
- debug_message(0, getpid(), (void*)debuglevel_class, sizeof(debuglevel_class));
+ debug_message(DEBUGLEVEL, getpid(), (void*)debuglevel_class, sizeof(debuglevel_class));
return True;
} else
return False;
@@ -238,14 +247,14 @@ BOOL debug_parse_levels(char *params_str)
/****************************************************************************
receive a "set debug level" message
****************************************************************************/
-void debug_message(int msg_type, pid_t src, void *buf, size_t len)
+void debug_message(int msg_level, pid_t src, void *buf, size_t len)
{
int i;
/* Set the new DEBUGLEVEL_CLASS array from the pased array */
memcpy(DEBUGLEVEL_CLASS, buf, sizeof(DEBUGLEVEL_CLASS));
- DEBUG(1,("INFO: Debug class %s level = %d (pid %u from pid %u)\n",
+ DEBUG(msg_level,("INFO: Debug class %s level = %d (pid %u from pid %u)\n",
classname_table[DBGC_ALL],
DEBUGLEVEL_CLASS[DBGC_ALL], (unsigned int)getpid(), (unsigned int)src));
diff --git a/source/lib/interface.c b/source/lib/interface.c
index 3a269294ed9..2e67b4a4a67 100644
--- a/source/lib/interface.c
+++ b/source/lib/interface.c
@@ -24,7 +24,6 @@
static struct iface_struct *probed_ifaces;
static int total_probed;
-struct in_addr ipzero;
struct in_addr allones_ip;
struct in_addr loopback_ip;
@@ -40,7 +39,8 @@ 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)
{
struct interface *i;
- if (zero_ip(ip)) return local_interfaces;
+ if (is_zero_ip(ip))
+ return local_interfaces;
for (i=local_interfaces;i;i=i->next)
if (CheckMask) {
@@ -102,8 +102,8 @@ static void interpret_interface(char *token)
char *p;
int i, added=0;
- ip = ipzero;
- nmask = ipzero;
+ zero_ip(&ip);
+ zero_ip(&nmask);
/* first check if it is an interface name */
for (i=0;i<total_probed;i++) {
@@ -171,7 +171,6 @@ void load_interfaces(void)
ptr = lp_interfaces();
- ipzero = *interpret_addr2("0.0.0.0");
allones_ip = *interpret_addr2("255.255.255.255");
loopback_ip = *interpret_addr2("127.0.0.1");
diff --git a/source/lib/kanji.c b/source/lib/kanji.c
index 39e9933842a..8a7494e6d77 100644
--- a/source/lib/kanji.c
+++ b/source/lib/kanji.c
@@ -59,8 +59,10 @@ char *(*multibyte_strtok)(char *, const char *) = (char *(*)(char *, const char
static size_t skip_non_multibyte_char(char);
static BOOL not_multibyte_char_1(char);
-char *(*_dos_to_unix)(char *, BOOL) = dos2unix_format;
-char *(*_unix_to_dos)(char *, BOOL) = unix2dos_format;
+char *(*_dos_to_unix)(char *) = dos2unix_format;
+char *(*_dos_to_unix_static)(const char *) = dos2unix_format_static;
+char *(*_unix_to_dos)(char *) = unix2dos_format;
+char *(*_unix_to_dos_static)(const char *) = unix2dos_format_static;
size_t (*_skip_multibyte_char)(char) = skip_non_multibyte_char;
BOOL (*is_multibyte_char_1)(char) = not_multibyte_char_1;
@@ -71,12 +73,15 @@ BOOL (*is_multibyte_char_1)(char) = not_multibyte_char_1;
* sj_to_sj in this file.
*/
-static char *sj_to_sj(char *from, BOOL overwrite);
+static char *sj_to_sj(char *from);
+static char *sj_to_sj_static(const char *from);
static size_t skip_kanji_multibyte_char(char);
static BOOL is_kanji_multibyte_char_1(char);
-char *(*_dos_to_unix)(char *, BOOL) = sj_to_sj;
-char *(*_unix_to_dos)(char *, BOOL) = sj_to_sj;
+char *(*_dos_to_unix)(char *) = sj_to_sj;
+char *(*_dos_to_unix_static)(const char *) = sj_to_sj_static;
+char *(*_unix_to_dos)(char *) = sj_to_sj;
+char *(*_unix_to_dos_static)(const char *) = sj_to_sj_static;
size_t (*_skip_multibyte_char)(char) = skip_kanji_multibyte_char;
int (*is_multibyte_char_1)(char) = is_kanji_multibyte_char_1;
@@ -458,12 +463,10 @@ static int sjis2euc (int hi, int lo)
return converted buffer
********************************************************************/
-static char *sj_to_euc(char *from, BOOL overwrite)
+static char *sj_to_euc_static(const char *from)
{
char *out;
- char *save;
- save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
if (is_shift_jis (*from)) {
int code = sjis2euc ((int) from[0] & 0xff, (int) from[1] & 0xff);
@@ -478,12 +481,13 @@ static char *sj_to_euc(char *from, BOOL overwrite)
}
}
*out = 0;
- if (overwrite) {
- pstrcpy((char *) save, (char *) cvtbuf);
- return (char *) save;
- } else {
- return cvtbuf;
- }
+ return cvtbuf;
+}
+
+static char *sj_to_euc(char *from)
+{
+ pstrcpy(from, sj_to_euc_static(from));
+ return from;
}
/*******************************************************************
@@ -491,12 +495,10 @@ static char *sj_to_euc(char *from, BOOL overwrite)
return converted buffer
********************************************************************/
-static char *euc_to_sj(char *from, BOOL overwrite)
+static char *euc_to_sj_static(const char *from)
{
char *out;
- char *save;
- save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3); ) {
if (is_euc (*from)) {
int code = euc2sjis ((int) from[0] & 0xff, (int) from[1] & 0xff);
@@ -511,13 +513,13 @@ static char *euc_to_sj(char *from, BOOL overwrite)
}
}
*out = 0;
+ return cvtbuf;
+}
- if (overwrite) {
- pstrcpy(save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
+static char *euc_to_sj(char *from)
+{
+ pstrcpy(from, euc_to_sj_static(from));
+ return from;
}
/*******************************************************************
@@ -700,13 +702,11 @@ static int euc3sjis (int hi, int lo, BOOL is_3byte)
return converted buffer
********************************************************************/
-static char *sj_to_euc3(char *from, BOOL overwrite)
+static char *sj_to_euc3_static(const char *from)
{
char *out;
- char *save;
int len;
- save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4);) {
if (is_shift_jis (*from)) {
int code = sjis3euc ((int) from[0] & 0xff, (int) from[1] & 0xff, &len);
@@ -724,24 +724,24 @@ static char *sj_to_euc3(char *from, BOOL overwrite)
}
}
*out = 0;
- if (overwrite) {
- pstrcpy((char *) save, (char *) cvtbuf);
- return (char *) save;
- } else {
- return cvtbuf;
- }
+ return cvtbuf;
+}
+
+static char *sj_to_euc3(char *from)
+{
+ pstrcpy(from, sj_to_euc3_static(from));
+ return from;
}
/*******************************************************************
Convert FROM contain EUC codes (with Sup-Kanji) to SHIFT JIS codes
return converted buffer
********************************************************************/
-static char *euc3_to_sj(char *from, BOOL overwrite)
+
+static char *euc3_to_sj_static(const char *from)
{
char *out;
- char *save;
- save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3); ) {
if (is_euc_sup (*from)) {
int code = euc3sjis((int) from[1] & 0xff, (int) from[2] & 0xff, True);
@@ -761,13 +761,13 @@ static char *euc3_to_sj(char *from, BOOL overwrite)
}
}
*out = 0;
+ return cvtbuf;
+}
- if (overwrite) {
- pstrcpy(save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
+static char *euc3_to_sj(char *from)
+{
+ pstrcpy(from, euc3_to_sj_static(from));
+ return from;
}
/*******************************************************************
@@ -846,14 +846,12 @@ static int jis2sjis(int hi, int lo)
return converted buffer
********************************************************************/
-static char *jis8_to_sj(char *from, BOOL overwrite)
+static char *jis8_to_sj_static(const char *from)
{
char *out;
int shifted;
- char *save;
shifted = _KJ_ROMAN;
- save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
if (is_esc (*from)) {
if (is_so1 (from[1]) && is_so2 (from[2])) {
@@ -887,12 +885,13 @@ normal:
}
*out = 0;
- if (overwrite) {
- pstrcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
+ return cvtbuf;
+}
+
+static char *jis8_to_sj(char *from)
+{
+ pstrcpy(from, jis8_to_sj_static(from));
+ return from;
}
/*******************************************************************
@@ -900,14 +899,12 @@ normal:
return converted buffer
********************************************************************/
-static char *sj_to_jis8(char *from, BOOL overwrite)
+static char *sj_to_jis8_static(const char *from)
{
char *out;
int shifted;
- char *save;
shifted = _KJ_ROMAN;
- save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
if (is_shift_jis (*from)) {
int code;
@@ -945,26 +942,26 @@ static char *sj_to_jis8(char *from, BOOL overwrite)
break;
}
*out = 0;
- if (overwrite) {
- pstrcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
+ return cvtbuf;
+}
+
+static char *sj_to_jis8(char *from)
+{
+ pstrcpy(from, sj_to_jis8_static(from));
+ return from;
}
/*******************************************************************
Convert FROM contain 7 bits JIS codes to SHIFT JIS codes
return converted buffer
********************************************************************/
-static char *jis7_to_sj(char *from, BOOL overwrite)
+
+static char *jis7_to_sj_static(const char *from)
{
char *out;
int shifted;
- char *save;
shifted = _KJ_ROMAN;
- save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
if (is_esc (*from)) {
if (is_so1 (from[1]) && is_so2 (from[2])) {
@@ -1004,26 +1001,26 @@ static char *jis7_to_sj(char *from, BOOL overwrite)
}
}
*out = 0;
- if (overwrite) {
- pstrcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
+ return cvtbuf;
}
+static char *jis7_to_sj(char *from)
+{
+ pstrcpy(from, jis7_to_sj_static(from));
+ return from;
+}
+
/*******************************************************************
Convert FROM contain SHIFT JIS codes to 7 bits JIS codes
return converted buffer
********************************************************************/
-static char *sj_to_jis7(char *from, BOOL overwrite)
+
+static char *sj_to_jis7_static(const char *from)
{
char *out;
int shifted;
- char *save;
shifted = _KJ_ROMAN;
- save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
if (is_shift_jis (*from)) {
int code;
@@ -1080,12 +1077,13 @@ static char *sj_to_jis7(char *from, BOOL overwrite)
break;
}
*out = 0;
- if (overwrite) {
- pstrcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
+ return cvtbuf;
+}
+
+static char *sj_to_jis7(char *from)
+{
+ pstrcpy(from, sj_to_jis7_static(from));
+ return from;
}
/*******************************************************************
@@ -1093,14 +1091,12 @@ static char *sj_to_jis7(char *from, BOOL overwrite)
return converted buffer
********************************************************************/
-static char *junet_to_sj(char *from, BOOL overwrite)
+static char *junet_to_sj_static(const char *from)
{
char *out;
int shifted;
- char *save;
shifted = _KJ_ROMAN;
- save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-3);) {
if (is_esc (*from)) {
if (is_so1 (from[1]) && is_so2 (from[2])) {
@@ -1137,26 +1133,26 @@ static char *junet_to_sj(char *from, BOOL overwrite)
}
}
*out = 0;
- if (overwrite) {
- pstrcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
+ return cvtbuf;
+}
+
+static char *junet_to_sj(char *from)
+{
+ pstrcpy(from, junet_to_sj_static(from));
+ return from;
}
/*******************************************************************
Convert FROM contain SHIFT JIS codes to 7 bits JIS(junet) codes
return converted buffer
********************************************************************/
-static char *sj_to_junet(char *from, BOOL overwrite)
+
+static char *sj_to_junet_static(const char *from)
{
char *out;
int shifted;
- char *save;
shifted = _KJ_ROMAN;
- save = (char *) from;
for (out = cvtbuf; *from && (out - cvtbuf < sizeof(cvtbuf)-4); ) {
if (is_shift_jis (*from)) {
int code;
@@ -1206,23 +1202,26 @@ static char *sj_to_junet(char *from, BOOL overwrite)
break;
}
*out = 0;
- if (overwrite) {
- pstrcpy (save, (char *) cvtbuf);
- return save;
- } else {
- return cvtbuf;
- }
+ return cvtbuf;
+}
+
+static char *sj_to_junet(char *from)
+{
+ pstrcpy(from, sj_to_junet_static(from));
+ return from;
}
/*******************************************************************
HEX <-> SJIS
********************************************************************/
/* ":xx" -> a byte */
-static char *hex_to_sj(char *from, BOOL overwrite)
+
+static char *hex_to_sj_static(const char *from)
{
- char *sp, *dp;
+ const char *sp;
+ char *dp;
- sp = (char *) from;
+ sp = from;
dp = cvtbuf;
while (*sp && (dp - cvtbuf < sizeof(cvtbuf)-3)) {
if (*sp == hex_tag && isxdigit((int)sp[1]) && isxdigit((int)sp[2])) {
@@ -1232,22 +1231,25 @@ static char *hex_to_sj(char *from, BOOL overwrite)
*dp++ = *sp++;
}
*dp = '\0';
- if (overwrite) {
- pstrcpy ((char *) from, (char *) cvtbuf);
- return (char *) from;
- } else {
- return cvtbuf;
- }
+ return cvtbuf;
}
+static char *hex_to_sj(char *from)
+{
+ pstrcpy(from, hex_to_sj_static(from));
+ return from;
+}
+
/*******************************************************************
kanji/kana -> ":xx"
********************************************************************/
-static char *sj_to_hex(char *from, BOOL overwrite)
+
+static char *sj_to_hex_static(const char *from)
{
- unsigned char *sp, *dp;
+ const unsigned char *sp;
+ unsigned char *dp;
- sp = (unsigned char*) from;
+ sp = from;
dp = (unsigned char*) cvtbuf;
while (*sp && (((char *)dp)- cvtbuf < sizeof(cvtbuf)-7)) {
if (is_kana(*sp)) {
@@ -1268,23 +1270,25 @@ static char *sj_to_hex(char *from, BOOL overwrite)
*dp++ = *sp++;
}
*dp = '\0';
- if (overwrite) {
- pstrcpy ((char *) from, (char *) cvtbuf);
- return (char *) from;
- } else {
- return cvtbuf;
- }
+ return cvtbuf;
+}
+
+static char *sj_to_hex(char *from)
+{
+ pstrcpy(from, sj_to_hex_static(from));
+ return from;
}
/*******************************************************************
CAP <-> SJIS
********************************************************************/
/* ":xx" CAP -> a byte */
-static char *cap_to_sj(char *from, BOOL overwrite)
+static char *cap_to_sj_static(const char *from)
{
- char *sp, *dp;
+ const char *sp;
+ char *dp;
- sp = (char *) from;
+ sp = (const char *) from;
dp = cvtbuf;
while (*sp && (dp- cvtbuf < sizeof(cvtbuf)-2)) {
/*
@@ -1300,22 +1304,24 @@ static char *cap_to_sj(char *from, BOOL overwrite)
*dp++ = *sp++;
}
*dp = '\0';
- if (overwrite) {
- pstrcpy ((char *) from, (char *) cvtbuf);
- return (char *) from;
- } else {
- return cvtbuf;
- }
+ return cvtbuf;
+}
+
+static char *cap_to_sj(char *from)
+{
+ pstrcpy(from, cap_to_sj_static(from));
+ return from;
}
/*******************************************************************
kanji/kana -> ":xx" - CAP format.
********************************************************************/
-static char *sj_to_cap(char *from, BOOL overwrite)
+static char *sj_to_cap_static(const char *from)
{
- unsigned char *sp, *dp;
+ const unsigned char *sp;
+ unsigned char *dp;
- sp = (unsigned char*) from;
+ sp = from;
dp = (unsigned char*) cvtbuf;
while (*sp && (((char *)dp) - cvtbuf < sizeof(cvtbuf)-4)) {
if (*sp >= 0x80) {
@@ -1328,39 +1334,42 @@ static char *sj_to_cap(char *from, BOOL overwrite)
}
}
*dp = '\0';
- if (overwrite) {
- pstrcpy ((char *) from, (char *) cvtbuf);
- return (char *) from;
- } else {
- return cvtbuf;
- }
+ return cvtbuf;
+}
+
+static char *sj_to_cap(char *from)
+{
+ pstrcpy(from, sj_to_cap_static(from));
+ return from;
}
/*******************************************************************
sj to sj
********************************************************************/
-static char *sj_to_sj(char *from, BOOL overwrite)
+
+static char *sj_to_sj_static(const char *from)
{
- if (!overwrite) {
- pstrcpy (cvtbuf, (char *) from);
+ pstrcpy (cvtbuf, from);
return cvtbuf;
- } else {
- return (char *) from;
- }
+}
+
+static char *sj_to_sj(char *from)
+{
+ return from;
}
/*******************************************************************
cp to utf8
********************************************************************/
-static char *cp_to_utf8(char *from, BOOL overwrite)
+static char *cp_to_utf8_static(const char *from)
{
unsigned char *dst;
- unsigned char *src;
+ const unsigned char *src;
smb_ucs2_t val;
int w;
size_t len;
- src = (unsigned char *)from;
+ src = (const unsigned char *)from;
dst = (unsigned char *)cvtbuf;
while (*src && (((char *)dst - cvtbuf) < sizeof(cvtbuf)-4)) {
len = _skip_multibyte_char(*src);
@@ -1385,25 +1394,26 @@ static char *cp_to_utf8(char *from, BOOL overwrite)
}
*dst++='\0';
- if (overwrite) {
- pstrcpy ((char *) from, (char *) cvtbuf);
- return (char *) from;
- } else {
- return cvtbuf;
- }
+ return cvtbuf;
+}
+
+static char *cp_to_utf8(char *from)
+{
+ pstrcpy(from, cp_to_utf8_static(from));
+ return from;
}
/*******************************************************************
utf8 to cp
********************************************************************/
-static char *utf8_to_cp(char *from, BOOL overwrite)
+static char *utf8_to_cp_static(const char *from)
{
- unsigned char *src;
+ const unsigned char *src;
unsigned char *dst;
smb_ucs2_t val;
int w;
- src = (unsigned char *)from;
+ src = (const unsigned char *)from;
dst = (unsigned char *)cvtbuf;
while (*src && ((char *)dst - cvtbuf < sizeof(cvtbuf)-4)) {
@@ -1425,12 +1435,13 @@ static char *utf8_to_cp(char *from, BOOL overwrite)
}
}
*dst++='\0';
- if (overwrite) {
- pstrcpy ((char *) from, (char *) cvtbuf);
- return (char *) from;
- } else {
- return cvtbuf;
- }
+ return cvtbuf;
+}
+
+static char *utf8_to_cp(char *from)
+{
+ pstrcpy(from, utf8_to_cp_static(from));
+ return from;
}
/************************************************************************
@@ -1443,50 +1454,72 @@ static void setup_string_function(int codes)
switch (codes) {
default:
_dos_to_unix = dos2unix_format;
+ _dos_to_unix_static = dos2unix_format_static;
_unix_to_dos = unix2dos_format;
+ _unix_to_dos_static = unix2dos_format_static;
break;
case SJIS_CODE:
_dos_to_unix = sj_to_sj;
+ _dos_to_unix_static = sj_to_sj_static;
_unix_to_dos = sj_to_sj;
+ _unix_to_dos_static = sj_to_sj_static;
break;
case EUC_CODE:
_dos_to_unix = sj_to_euc;
+ _dos_to_unix_static = sj_to_euc_static;
_unix_to_dos = euc_to_sj;
+ _unix_to_dos_static = euc_to_sj_static;
break;
case JIS7_CODE:
_dos_to_unix = sj_to_jis7;
+ _dos_to_unix_static = sj_to_jis7_static;
_unix_to_dos = jis7_to_sj;
+ _unix_to_dos_static = jis7_to_sj_static;
break;
case JIS8_CODE:
_dos_to_unix = sj_to_jis8;
+ _dos_to_unix_static = sj_to_jis8_static;
_unix_to_dos = jis8_to_sj;
+ _unix_to_dos_static = jis8_to_sj_static;
break;
case JUNET_CODE:
_dos_to_unix = sj_to_junet;
+ _dos_to_unix_static = sj_to_junet_static;
_unix_to_dos = junet_to_sj;
+ _unix_to_dos_static = junet_to_sj_static;
break;
case HEX_CODE:
_dos_to_unix = sj_to_hex;
+ _dos_to_unix_static = sj_to_hex_static;
_unix_to_dos = hex_to_sj;
+ _unix_to_dos_static = hex_to_sj_static;
break;
case CAP_CODE:
_dos_to_unix = sj_to_cap;
+ _dos_to_unix_static = sj_to_cap_static;
_unix_to_dos = cap_to_sj;
+ _unix_to_dos_static = cap_to_sj_static;
break;
+
case UTF8_CODE:
_dos_to_unix = cp_to_utf8;
+ _dos_to_unix_static = cp_to_utf8_static;
_unix_to_dos = utf8_to_cp;
+ _unix_to_dos_static = utf8_to_cp_static;
break;
+
case EUC3_CODE:
_dos_to_unix = sj_to_euc3;
+ _dos_to_unix_static = sj_to_euc3_static;
_unix_to_dos = euc3_to_sj;
+ _unix_to_dos_static = euc3_to_sj_static;
break;
}
}
@@ -1680,12 +1713,10 @@ void initialize_multibyte_vectors( int client_codepage)
(to catalog file encoding) is not needed because
they are using same character codes.
**************************************************** */
-static char *no_conversion(char *str, BOOL bOverwrite)
+static char *no_conversion_static(const char *str)
{
static pstring temp;
- if(bOverwrite)
- return str;
pstrcpy(temp, str);
return temp;
}
-char *(*_dos_to_dos)(char *, BOOL) = no_conversion;
+char *(*_dos_to_dos_static)(const char *) = no_conversion_static;
diff --git a/source/lib/messages.c b/source/lib/messages.c
index b4fd82139ea..518b7d51c1e 100644
--- a/source/lib/messages.c
+++ b/source/lib/messages.c
@@ -1,8 +1,8 @@
/*
- Unix SMB/Netbios implementation.
- Version 3.0
+ Unix SMB/CIFS implementation.
Samba internal messaging functions
Copyright (C) Andrew Tridgell 2000
+ Copyright (C) 2001 by Martin Pool
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
@@ -19,13 +19,22 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* this module is used for internal messaging between Samba daemons.
+/**
+ @defgroups messages Internal messaging framework
+ @{
+ @file messages.c
+
+ This module is used for internal messaging between Samba daemons.
The idea is that if a part of Samba wants to do communication with
another Samba process then it will do a message_register() of a
dispatch function, and use message_send_pid() to send messages to
that process.
+ The dispatch function is given the pid of the sender, and it can
+ use that to reply by message_send_pid(). See ping_message() for a
+ simple example.
+
This system doesn't have any inherent size limitations but is not
very efficient for large messages or when messages are sent in very
quick succession.
@@ -151,7 +160,8 @@ static BOOL message_notify(pid_t pid)
Send a message to a particular pid.
****************************************************************************/
-BOOL message_send_pid(pid_t pid, int msg_type, void *buf, size_t len, BOOL duplicates_allowed)
+BOOL message_send_pid(pid_t pid, int msg_type, const void *buf, size_t len,
+ BOOL duplicates_allowed)
{
TDB_DATA kbuf;
TDB_DATA dbuf;
@@ -198,7 +208,7 @@ BOOL message_send_pid(pid_t pid, int msg_type, void *buf, size_t len, BOOL dupli
*/
if (!memcmp(ptr, &rec, sizeof(rec))) {
- if (!len || (len && !memcmp( ptr + sizeof(rec), (char *)buf, len))) {
+ if (!len || (len && !memcmp( ptr + sizeof(rec), buf, len))) {
DEBUG(10,("message_send_pid: discarding duplicate message.\n"));
SAFE_FREE(dbuf.dptr);
tdb_chainunlock(tdb, kbuf);
@@ -303,6 +313,7 @@ void message_dispatch(void)
void *buf;
size_t len;
struct dispatch_fns *dfn;
+ int n_handled;
if (!received_signal) return;
@@ -311,12 +322,21 @@ void message_dispatch(void)
received_signal = 0;
while (message_recv(&msg_type, &src, &buf, &len)) {
+ DEBUG(10,("message_dispatch: received msg_type=%d src_pid=%d\n",
+ msg_type, (int) src));
+ n_handled = 0;
for (dfn = dispatch_fns; dfn; dfn = dfn->next) {
if (dfn->msg_type == msg_type) {
DEBUG(10,("message_dispatch: processing message of type %d.\n", msg_type));
dfn->fn(msg_type, src, buf, len);
+ n_handled++;
}
}
+ if (!n_handled) {
+ DEBUG(5,("message_dispatch: warning: no handlers registed for "
+ "msg_type %d in pid%d\n",
+ msg_type, getpid()));
+ }
SAFE_FREE(buf);
}
}
@@ -366,9 +386,10 @@ void message_deregister(int msg_type)
struct msg_all {
int msg_type;
- void *buf;
+ const void *buf;
size_t len;
BOOL duplicates;
+ int n_sent;
};
/****************************************************************************
@@ -390,8 +411,9 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void
/* if the msg send fails because the pid was not found (i.e. smbd died),
* the msg has already been deleted from the messages.tdb.*/
- if (!message_send_pid(crec.pid, msg_all->msg_type, msg_all->buf, msg_all->len,
- msg_all->duplicates)) {
+ if (!message_send_pid(crec.pid, msg_all->msg_type,
+ msg_all->buf, msg_all->len,
+ msg_all->duplicates)) {
/* if the pid was not found delete the entry from connections.tdb */
if (errno == ESRCH) {
@@ -400,16 +422,26 @@ static int traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA kbuf, TDB_DATA dbuf, void
tdb_delete(the_tdb, kbuf);
}
}
+ msg_all->n_sent++;
return 0;
}
-/****************************************************************************
- This is a useful function for sending messages to all smbd processes.
- It isn't very efficient, but should be OK for the sorts of applications that
- use it. When we need efficient broadcast we can add it.
-****************************************************************************/
-
-BOOL message_send_all(TDB_CONTEXT *conn_tdb, int msg_type, void *buf, size_t len, BOOL duplicates_allowed)
+/**
+ * Send a message to all smbd processes.
+ *
+ * It isn't very efficient, but should be OK for the sorts of
+ * applications that use it. When we need efficient broadcast we can add
+ * it.
+ *
+ * @param n_sent Set to the number of messages sent. This should be
+ * equal to the number of processes, but be careful for races.
+ *
+ * @return True for success.
+ **/
+BOOL message_send_all(TDB_CONTEXT *conn_tdb, int msg_type,
+ const void *buf, size_t len,
+ BOOL duplicates_allowed,
+ int *n_sent)
{
struct msg_all msg_all;
@@ -417,7 +449,73 @@ BOOL message_send_all(TDB_CONTEXT *conn_tdb, int msg_type, void *buf, size_t len
msg_all.buf = buf;
msg_all.len = len;
msg_all.duplicates = duplicates_allowed;
+ msg_all.n_sent = 0;
tdb_traverse(conn_tdb, traverse_fn, &msg_all);
+ if (n_sent)
+ *n_sent = msg_all.n_sent;
return True;
}
+
+/** @} **/
+
+static VOLATILE sig_atomic_t gotalarm;
+
+/***************************************************************
+ Signal function to tell us we timed out.
+****************************************************************/
+
+static void gotalarm_sig(void)
+{
+ gotalarm = 1;
+}
+
+/*
+ lock the messaging tdb based on a string - this is used as a primitive form of mutex
+ between smbd instances.
+*/
+BOOL message_named_mutex(char *name, unsigned int timeout)
+{
+ TDB_DATA key;
+ int ret;
+
+ if (!message_init())
+ return False;
+
+ key.dptr = name;
+ key.dsize = strlen(name)+1;
+
+ if (timeout) {
+ gotalarm = 0;
+ CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
+ alarm(timeout);
+ }
+
+ ret = tdb_chainlock(tdb, key);
+
+ if (timeout) {
+ alarm(0);
+ CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
+ if (gotalarm)
+ return False;
+ }
+
+ if (ret == 0)
+ DEBUG(10,("message_named_mutex: got mutex for %s\n", name ));
+
+ return (ret == 0);
+}
+
+/*
+ unlock a named mutex
+*/
+void message_named_mutex_release(char *name)
+{
+ TDB_DATA key;
+
+ key.dptr = name;
+ key.dsize = strlen(name)+1;
+
+ tdb_chainunlock(tdb, key);
+ DEBUG(10,("message_named_mutex: released mutex for %s\n", name ));
+}
diff --git a/source/lib/pidfile.c b/source/lib/pidfile.c
index 25ca1944111..a856541ca89 100644
--- a/source/lib/pidfile.c
+++ b/source/lib/pidfile.c
@@ -37,7 +37,7 @@ pid_t pidfile_pid(char *name)
unsigned ret;
pstring pidFile;
- slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_lockdir(), name);
+ slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_piddir(), name);
fd = sys_open(pidFile, O_NONBLOCK | O_RDONLY, 0644);
if (fd == -1) {
@@ -70,7 +70,7 @@ pid_t pidfile_pid(char *name)
return 0;
}
-/* create a pid file in the lock directory. open it and leave it locked */
+/* create a pid file in the pid directory. open it and leave it locked */
void pidfile_create(char *name)
{
int fd;
@@ -78,7 +78,7 @@ void pidfile_create(char *name)
pstring pidFile;
pid_t pid;
- slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_lockdir(), name);
+ slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_piddir(), name);
pid = pidfile_pid(name);
if (pid != 0) {
diff --git a/source/lib/replace.c b/source/lib/replace.c
index 16d7450d69e..dd50ff035e0 100644
--- a/source/lib/replace.c
+++ b/source/lib/replace.c
@@ -1,6 +1,5 @@
/*
- Unix SMB/Netbios implementation.
- Version 1.9.
+ Unix SMB/CIFS implementation.
replacement routines for broken systems
Copyright (C) Andrew Tridgell 1992-1998
@@ -24,7 +23,6 @@
void replace_dummy(void);
void replace_dummy(void) {}
-
#ifndef HAVE_FTRUNCATE
/*******************************************************************
ftruncate for operating systems that don't have it
@@ -42,6 +40,42 @@ ftruncate for operating systems that don't have it
#endif /* HAVE_FTRUNCATE */
+#ifndef HAVE_STRLCPY
+/* like strncpy but does not 0 fill the buffer and always null
+ terminates. bufsize is the size of the destination buffer */
+ size_t strlcpy(char *d, const char *s, size_t bufsize)
+{
+ size_t len = strlen(s);
+ size_t ret = len;
+ if (bufsize <= 0) return 0;
+ if (len >= bufsize) len = bufsize-1;
+ memcpy(d, s, len);
+ d[len] = 0;
+ return ret;
+}
+#endif
+
+#ifndef HAVE_STRLCAT
+/* like strncat but does not 0 fill the buffer and always null
+ terminates. bufsize is the length of the buffer, which should
+ be one more than the maximum resulting string length */
+ size_t strlcat(char *d, const char *s, size_t bufsize)
+{
+ size_t len1 = strlen(d);
+ size_t len2 = strlen(s);
+ size_t ret = len1 + len2;
+
+ if (len1+len2 >= bufsize) {
+ len2 = bufsize - (len1+1);
+ }
+ if (len2 > 0) {
+ memcpy(d+len1, s, len2);
+ d[len1+len2] = 0;
+ }
+ return ret;
+}
+#endif
+
#ifndef HAVE_MKTIME
/*******************************************************************
a mktime() replacement for those who don't have it - contributed by
@@ -125,7 +159,7 @@ Corrections by richard.kettlewell@kewill.com
/*
* Search for a match in a netgroup. This replaces it on broken systems.
*/
- int innetgr(char *group,char *host,char *user,char *dom)
+ int innetgr(const char *group,const char *host,const char *user,const char *dom)
{
char *hst, *usr, *dm;
diff --git a/source/lib/snprintf.c b/source/lib/snprintf.c
index 0b0bdb0b335..27336261086 100644
--- a/source/lib/snprintf.c
+++ b/source/lib/snprintf.c
@@ -57,6 +57,12 @@
#ifndef NO_CONFIG_H /* for some tests */
#include "config.h"
+#else
+#define NULL 0
+#endif
+
+#ifdef TEST_SNPRINTF /* need math library headers for testing */
+#include <math.h>
#endif
#ifdef HAVE_STRING_H
@@ -661,9 +667,8 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
/* Convert integer part */
do {
- temp = intpart;
- my_modf(intpart*0.1, &intpart);
- temp = temp*0.1;
+ temp = intpart*0.1;
+ my_modf(temp, &intpart);
index = (int) ((temp -intpart +0.05)* 10.0);
/* index = (int) (((double)(temp*0.1) -intpart +0.05) *10.0); */
/* printf ("%llf, %f, %x\n", temp, intpart, index); */
@@ -677,9 +682,8 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
if (fracpart)
{
do {
- temp = fracpart;
- my_modf(fracpart*0.1, &fracpart);
- temp = temp*0.1;
+ temp = fracpart*0.1;
+ my_modf(temp, &fracpart);
index = (int) ((temp -fracpart +0.05)* 10.0);
/* index = (int) ((((temp/10) -fracpart) +0.05) *10); */
/* printf ("%lf, %lf, %ld\n", temp, fracpart, index); */
@@ -731,14 +735,14 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen,
if (max > 0) {
dopr_outch (buffer, currlen, maxlen, '.');
+ while (zpadlen > 0) {
+ dopr_outch (buffer, currlen, maxlen, '0');
+ --zpadlen;
+ }
+
while (fplace > 0)
dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]);
}
-
- while (zpadlen > 0) {
- dopr_outch (buffer, currlen, maxlen, '0');
- --zpadlen;
- }
while (padlen < 0) {
dopr_outch (buffer, currlen, maxlen, ' ');
@@ -858,7 +862,7 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
NULL
};
double fp_nums[] = { 6442452944.1234, -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996,
- 0.9996, 1.996, 4.136, 0};
+ 0.9996, 1.996, 4.136, 5.030201, 0};
char *int_fmt[] = {
"%-1.5d",
"%1.5d",
@@ -953,8 +957,10 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c)
{
double v0 = 0.12345678901234567890123456789012345678901;
for (x=0; x<100; x++) {
- snprintf(buf1, sizeof(buf1), "%1.1f", v0*pow(10, x));
- sprintf(buf2, "%1.1f", v0*pow(10, x));
+ double p = pow(10, x);
+ double r = v0*p;
+ snprintf(buf1, sizeof(buf1), "%1.1f", r);
+ sprintf(buf2, "%1.1f", r);
if (strcmp(buf1, buf2)) {
printf("we seem to support %d digits\n", x-1);
break;
diff --git a/source/lib/substitute.c b/source/lib/substitute.c
index 387b07bc512..c1ac1f504a3 100644
--- a/source/lib/substitute.c
+++ b/source/lib/substitute.c
@@ -168,6 +168,7 @@ static char *automount_server(char *user_name)
void standard_sub_basic(char *str)
{
+ extern pstring global_myname;
char *p, *s;
fstring pidstr;
struct passwd *pass;
@@ -197,7 +198,21 @@ void standard_sub_basic(char *str)
string_sub(p,"%D", tmp_str,l);
break;
case 'I' : string_sub(p,"%I", client_addr(),l); break;
- case 'L' : string_sub(p,"%L", local_machine,l); break;
+ case 'L' :
+ if (*local_machine)
+ string_sub(p,"%L", local_machine,l);
+ else {
+ char *ns = p;
+
+ string_sub(p,"%L", global_myname,l);
+ while (*ns)
+ {
+ if (isupper(*ns))
+ *ns = tolower(*ns);
+ ns++;
+ }
+ }
+ break;
case 'M' : string_sub(p,"%M", client_name(),l); break;
case 'R' : string_sub(p,"%R", remote_proto,l); break;
case 'T' : string_sub(p,"%T", timestring(False),l); break;
diff --git a/source/lib/sysacls.c b/source/lib/sysacls.c
index 743c098bebd..9ce04e596b9 100644
--- a/source/lib/sysacls.c
+++ b/source/lib/sysacls.c
@@ -1204,7 +1204,7 @@ SMB_ACL_T sys_acl_get_fd(int fd)
* can use the relative path.
*/
- return sys_acl_get_file(dos_to_unix(fsp->fsp_name,False), SMB_ACL_TYPE_ACCESS);
+ return sys_acl_get_file(dos_to_unix_static(fsp->fsp_name), SMB_ACL_TYPE_ACCESS);
}
int sys_acl_clear_perms(SMB_ACL_PERMSET_T permset_d)
@@ -1892,7 +1892,7 @@ int sys_acl_set_fd(int fd, SMB_ACL_T acl_d)
* can use the relative path.
*/
- return sys_acl_set_file(dos_to_unix(fsp->fsp_name,False), SMB_ACL_TYPE_ACCESS, acl_d);
+ return sys_acl_set_file(dos_to_unix_static(fsp->fsp_name), SMB_ACL_TYPE_ACCESS, acl_d);
}
int sys_acl_delete_def_file(const char *path)
diff --git a/source/lib/system.c b/source/lib/system.c
index a4420f5c6c2..a449600b21f 100644
--- a/source/lib/system.c
+++ b/source/lib/system.c
@@ -74,6 +74,104 @@ int sys_usleep(long usecs)
}
/*******************************************************************
+A read wrapper that will deal with EINTR.
+********************************************************************/
+
+ssize_t sys_read(int fd, void *buf, size_t count)
+{
+ ssize_t ret;
+
+ do {
+ ret = read(fd, buf, count);
+ } while (ret == -1 && errno == EINTR);
+ return ret;
+}
+
+/*******************************************************************
+A write wrapper that will deal with EINTR.
+********************************************************************/
+
+ssize_t sys_write(int fd, const void *buf, size_t count)
+{
+ ssize_t ret;
+
+ do {
+ ret = write(fd, buf, count);
+ } while (ret == -1 && errno == EINTR);
+ return ret;
+}
+
+/*******************************************************************
+A send wrapper that will deal with EINTR.
+********************************************************************/
+
+ssize_t sys_send(int s, const void *msg, size_t len, int flags)
+{
+ ssize_t ret;
+
+ do {
+ ret = send(s, msg, len, flags);
+ } while (ret == -1 && errno == EINTR);
+ return ret;
+}
+
+/*******************************************************************
+A sendto wrapper that will deal with EINTR.
+********************************************************************/
+
+ssize_t sys_sendto(int s, const void *msg, size_t len, int flags, const struct sockaddr *to, socklen_t tolen)
+{
+ ssize_t ret;
+
+ do {
+ ret = sendto(s, msg, len, flags, to, tolen);
+ } while (ret == -1 && errno == EINTR);
+ return ret;
+}
+
+/*******************************************************************
+A recvfrom wrapper that will deal with EINTR.
+********************************************************************/
+
+ssize_t sys_recvfrom(int s, void *buf, size_t len, int flags, struct sockaddr *from, socklen_t *fromlen)
+{
+ ssize_t ret;
+
+ do {
+ ret = recvfrom(s, buf, len, flags, from, fromlen);
+ } while (ret == -1 && errno == EINTR);
+ return ret;
+}
+
+/*******************************************************************
+A fcntl wrapper that will deal with EINTR.
+********************************************************************/
+
+int sys_fcntl_ptr(int fd, int cmd, void *arg)
+{
+ int ret;
+
+ do {
+ ret = fcntl(fd, cmd, arg);
+ } while (ret == -1 && errno == EINTR);
+ return ret;
+}
+
+/*******************************************************************
+A fcntl wrapper that will deal with EINTR.
+********************************************************************/
+
+int sys_fcntl_long(int fd, int cmd, long arg)
+{
+ int ret;
+
+ do {
+ ret = fcntl(fd, cmd, arg);
+ } while (ret == -1 && errno == EINTR);
+ return ret;
+}
+
+/*******************************************************************
A stat() wrapper that will deal with 64 bit filesizes.
********************************************************************/
@@ -1172,7 +1270,7 @@ int sys_pclose(int fd)
void *sys_dlopen(const char *name, int flags)
{
-#ifdef HAVE_LIBDL
+#if defined(HAVE_DLOPEN)
return dlopen(name, flags);
#else
return NULL;
@@ -1181,7 +1279,7 @@ void *sys_dlopen(const char *name, int flags)
void *sys_dlsym(void *handle, char *symbol)
{
-#ifdef HAVE_LIBDL
+#if defined(HAVE_DLSYM)
return dlsym(handle, symbol);
#else
return NULL;
@@ -1190,7 +1288,7 @@ void *sys_dlsym(void *handle, char *symbol)
int sys_dlclose (void *handle)
{
-#ifdef HAVE_LIBDL
+#if defined(HAVE_DLCLOSE)
return dlclose(handle);
#else
return 0;
@@ -1199,9 +1297,37 @@ int sys_dlclose (void *handle)
const char *sys_dlerror(void)
{
-#ifdef HAVE_LIBDL
+#if defined(HAVE_DLERROR)
return dlerror();
#else
return NULL;
#endif
}
+
+/**************************************************************************
+ Wrapper for Admin Logs.
+****************************************************************************/
+
+void sys_adminlog(int priority, const char *format_str, ...)
+{
+ va_list ap;
+ int ret;
+ char **msgbuf = NULL;
+
+ if (!lp_admin_log())
+ return;
+
+ va_start( ap, format_str );
+ ret = vasprintf( msgbuf, format_str, ap );
+ va_end( ap );
+
+ if (ret == -1)
+ return;
+
+#if defined(HAVE_SYSLOG)
+ syslog( priority, "%s", *msgbuf );
+#else
+ DEBUG(0,("%s", *msgbuf ));
+#endif
+ SAFE_FREE(*msgbuf);
+}
diff --git a/source/lib/talloc.c b/source/lib/talloc.c
index fb5c3495fe4..6ac784a9297 100644
--- a/source/lib/talloc.c
+++ b/source/lib/talloc.c
@@ -1,8 +1,8 @@
/*
- Unix SMB/Netbios implementation.
- Version 3.0
+ Samba Unix SMB/CIFS implementation.
Samba temporary memory allocation functions
Copyright (C) Andrew Tridgell 2000
+ Copyright (C) 2001, 2002 by Martin Pool <mbp@samba.org>
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
@@ -19,7 +19,11 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* this is a very simple temporary memory allocator. To use it do the following:
+/**
+ @defgroup talloc Simple memory allocator
+ @{
+
+ This is a very simple temporary memory allocator. To use it do the following:
1) when you first want to allocate a pool of meomry use
talloc_init() and save the resulting context pointer somewhere
@@ -31,58 +35,158 @@
talloc does not zero the memory. It guarantees memory of a
TALLOC_ALIGN alignment
+
+ @sa talloc.h
*/
+/**
+ * @todo We could allocate both the talloc_chunk structure, and the
+ * memory it contains all in one allocation, which might be a bit
+ * faster and perhaps use less memory overhead.
+ *
+ * That smells like a premature optimization, though. -- mbp
+ **/
+
+/**
+ * If you want testing for memory corruption, link with dmalloc or use
+ * Insure++. It doesn't seem useful to duplicate them here.
+ **/
+
#include "includes.h"
-/* initialise talloc context. */
+struct talloc_chunk {
+ struct talloc_chunk *next;
+ size_t size;
+ void *ptr;
+};
+
+
+struct talloc_ctx {
+ struct talloc_chunk *list;
+ size_t total_alloc_size;
+
+ /** The name recorded for this pool, if any. Should describe
+ * the purpose for which it was allocated. The string is
+ * allocated within the pool. **/
+ char *name;
+
+ /** Pointer to the next allocate talloc pool, so that we can
+ * summarize all talloc memory usage. **/
+ struct talloc_ctx *next_ctx;
+};
+
+
+/**
+ * Start of linked list of all talloc pools.
+ *
+ * @todo We should turn the global list off when using Insure++,
+ * otherwise all the memory will be seen as still reachable.
+ **/
+TALLOC_CTX *list_head = NULL;
+
+
+/**
+ * Add to the global list
+ **/
+static void talloc_enroll(TALLOC_CTX *t)
+{
+ t->next_ctx = list_head;
+ list_head = t;
+}
+
+
+static void talloc_disenroll(TALLOC_CTX *t)
+{
+ TALLOC_CTX **ttmp;
+
+ /* Use a double-* so that no special case is required for the
+ * list head. */
+ for (ttmp = &list_head; *ttmp; ttmp = &((*ttmp)->next_ctx))
+ if (*ttmp == t) {
+ /* ttmp is the link that points to t, either
+ * list_head or the next_ctx link in its
+ * predecessor */
+ *ttmp = t->next_ctx;
+ t->next_ctx = NULL; /* clobber */
+ return;
+ }
+ abort(); /* oops, this talloc was already
+ * clobbered or something else went
+ * wrong. */
+}
+
+
+/** Create a new talloc context. **/
TALLOC_CTX *talloc_init(void)
{
TALLOC_CTX *t;
- t = (TALLOC_CTX *)malloc(sizeof(*t));
- if (!t) return NULL;
+ t = (TALLOC_CTX *)malloc(sizeof(TALLOC_CTX));
+ if (t) {
+ t->list = NULL;
+ t->total_alloc_size = 0;
+ t->name = NULL;
+ talloc_enroll(t);
+ }
- t->list = NULL;
- t->total_alloc_size = 0;
+ return t;
+}
+
+
+
+/**
+ * Create a new talloc context, with a name specifying its purpose.
+ * Please call this in preference to talloc_init().
+ **/
+ TALLOC_CTX *talloc_init_named(char const *fmt, ...)
+{
+ TALLOC_CTX *t;
+ va_list ap;
+ t = talloc_init();
+ if (t && fmt) {
+ va_start(ap, fmt);
+ t->name = talloc_vasprintf(t, fmt, ap);
+ va_end(ap);
+ }
+
return t;
}
-/* allocate a bit of memory from the specified pool */
+
+/** Allocate a bit of memory from the specified pool **/
void *talloc(TALLOC_CTX *t, size_t size)
{
void *p;
struct talloc_chunk *tc;
- if (size == 0) return NULL;
+ if (!t || size == 0) return NULL;
p = malloc(size);
- if (!p) return p;
-
- tc = malloc(sizeof(*tc));
- if (!tc) {
- SAFE_FREE(p);
- return NULL;
+ if (p) {
+ tc = malloc(sizeof(*tc));
+ if (tc) {
+ tc->ptr = p;
+ tc->size = size;
+ tc->next = t->list;
+ t->list = tc;
+ t->total_alloc_size += size;
+ }
+ else {
+ SAFE_FREE(p);
+ }
}
-
- tc->ptr = p;
- tc->size = size;
- tc->next = t->list;
- t->list = tc;
- t->total_alloc_size += size;
-
return p;
}
-/* a talloc version of realloc */
+/** A talloc version of realloc */
void *talloc_realloc(TALLOC_CTX *t, void *ptr, size_t size)
{
struct talloc_chunk *tc;
void *new_ptr;
/* size zero is equivalent to free() */
- if (size == 0)
+ if (!t || size == 0)
return NULL;
/* realloc(NULL) is equavalent to malloc() */
@@ -103,7 +207,8 @@ void *talloc_realloc(TALLOC_CTX *t, void *ptr, size_t size)
return NULL;
}
-/* destroy a whole pool */
+/** Destroy all the memory allocated inside @p t, but not @p t
+ * itself. */
void talloc_destroy_pool(TALLOC_CTX *t)
{
struct talloc_chunk *c;
@@ -118,27 +223,40 @@ void talloc_destroy_pool(TALLOC_CTX *t)
t->list = c;
}
- t->list = NULL;
t->total_alloc_size = 0;
}
-/* destroy a whole pool including the context */
+/** Destroy a whole pool including the context */
void talloc_destroy(TALLOC_CTX *t)
{
if (!t)
return;
+
talloc_destroy_pool(t);
- memset(t, 0, sizeof(*t));
+ talloc_disenroll(t);
+ memset(t, 0, sizeof(TALLOC_CTX));
SAFE_FREE(t);
}
-/* return the current total size of the pool. */
+/** Return the current total size of the pool. */
size_t talloc_pool_size(TALLOC_CTX *t)
{
- return t->total_alloc_size;
+ if (t)
+ return t->total_alloc_size;
+ else
+ return 0;
}
-/* talloc and zero memory. */
+const char * talloc_pool_name(TALLOC_CTX const *t)
+{
+ if (t)
+ return t->name;
+ else
+ return NULL;
+}
+
+
+/** talloc and zero memory. */
void *talloc_zero(TALLOC_CTX *t, size_t size)
{
void *p = talloc(t, size);
@@ -149,21 +267,175 @@ void *talloc_zero(TALLOC_CTX *t, size_t size)
return p;
}
-/* memdup with a talloc. */
-void *talloc_memdup(TALLOC_CTX *t, void *p, size_t size)
+/** memdup with a talloc. */
+void *talloc_memdup(TALLOC_CTX *t, const void *p, size_t size)
{
void *newp = talloc(t,size);
- if (!newp)
- return 0;
-
- memcpy(newp, p, size);
+ if (newp)
+ memcpy(newp, p, size);
return newp;
}
-/* strdup with a talloc */
-char *talloc_strdup(TALLOC_CTX *t, char *p)
+/** strdup with a talloc */
+char *talloc_strdup(TALLOC_CTX *t, const char *p)
+{
+ if (p)
+ return talloc_memdup(t, p, strlen(p) + 1);
+ else
+ return NULL;
+}
+
+/**
+ * Perform string formatting, and return a pointer to newly allocated
+ * memory holding the result, inside a memory pool.
+ **/
+ char *talloc_asprintf(TALLOC_CTX *t, const char *fmt, ...)
+{
+ va_list ap;
+ char *ret;
+
+ va_start(ap, fmt);
+ ret = talloc_vasprintf(t, fmt, ap);
+ va_end(ap);
+ return ret;
+}
+
+
+ char *talloc_vasprintf(TALLOC_CTX *t, const char *fmt, va_list ap)
+{
+ int len;
+ char *ret;
+
+ len = vsnprintf(NULL, 0, fmt, ap);
+
+ ret = talloc(t, len+1);
+ if (ret)
+ vsnprintf(ret, len+1, fmt, ap);
+
+ return ret;
+}
+
+
+/**
+ * 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 string buffer.
+ **/
+ char *talloc_asprintf_append(TALLOC_CTX *t, char *s,
+ const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ s = talloc_vasprintf_append(t, s, fmt, ap);
+ va_end(ap);
+ 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.
+ **/
+ char *talloc_vasprintf_append(TALLOC_CTX *t, char *s,
+ const char *fmt, va_list ap)
+{
+ int len, s_len;
+
+ s_len = strlen(s);
+ len = vsnprintf(NULL, 0, fmt, ap);
+
+ s = talloc_realloc(t, s, s_len + len+1);
+ if (!s) return NULL;
+
+ vsnprintf(s+s_len, len+1, fmt, ap);
+
+ return s;
+}
+
+
+/**
+ * Return a human-readable description of all talloc memory usage.
+ * The result is allocated from @p t.
+ **/
+char *talloc_describe_all(TALLOC_CTX *rt)
{
- return talloc_memdup(t, p, strlen(p) + 1);
+ int n_pools = 0, total_chunks = 0;
+ size_t total_bytes = 0;
+ TALLOC_CTX *it;
+ char *s;
+
+ if (!rt) return NULL;
+
+ s = talloc_asprintf(rt, "global talloc allocations in pid: %u\n",
+ (unsigned) sys_getpid());
+ s = talloc_asprintf_append(rt, s, "%-40s %8s %8s\n",
+ "name", "chunks", "bytes");
+ s = talloc_asprintf_append(rt, s, "%-40s %8s %8s\n",
+ "----------------------------------------",
+ "--------",
+ "--------");
+
+ for (it = list_head; it; it = it->next_ctx) {
+ size_t bytes;
+ int n_chunks;
+ fstring what;
+
+ n_pools++;
+
+ talloc_get_allocation(it, &bytes, &n_chunks);
+
+ if (it->name)
+ fstrcpy(what, it->name);
+ else
+ slprintf(what, sizeof what, "@%p", it);
+
+ s = talloc_asprintf_append(rt, s, "%-40s %8u %8u\n",
+ what,
+ (unsigned) n_chunks,
+ (unsigned) bytes);
+ total_bytes += bytes;
+ total_chunks += n_chunks;
+ }
+
+ s = talloc_asprintf_append(rt, s, "%-40s %8s %8s\n",
+ "----------------------------------------",
+ "--------",
+ "--------");
+
+ s = talloc_asprintf_append(rt, s, "%-40s %8u %8u\n",
+ "TOTAL",
+ (unsigned) total_chunks, (unsigned) total_bytes);
+
+ return s;
}
+
+
+
+/**
+ * Return an estimated memory usage for the specified pool. This does
+ * not include memory used by the underlying malloc implementation.
+ **/
+void talloc_get_allocation(TALLOC_CTX *t,
+ size_t *total_bytes,
+ int *n_chunks)
+{
+ struct talloc_chunk *chunk;
+
+ if (t) {
+ *total_bytes = 0;
+ *n_chunks = 0;
+
+ for (chunk = t->list; chunk; chunk = chunk->next) {
+ n_chunks[0]++;
+ *total_bytes += chunk->size;
+ }
+ }
+}
+
+
+/** @} */
diff --git a/source/lib/username.c b/source/lib/username.c
index 7ad2341d627..2bf289b6771 100644
--- a/source/lib/username.c
+++ b/source/lib/username.c
@@ -239,9 +239,9 @@ struct passwd *Get_Pwnam(char *user,BOOL allow_change)
/* try in all lower case first as this is the most
common case on UNIX systems */
- unix_to_dos(user, True);
+ unix_to_dos(user);
strlower(user);
- dos_to_unix(user, True);
+ dos_to_unix(user);
ret = _Get_Pwnam(user);
if (ret)
@@ -260,9 +260,9 @@ struct passwd *Get_Pwnam(char *user,BOOL allow_change)
}
/* finally, try in all caps if that is a new case */
- unix_to_dos(user, True);
+ unix_to_dos(user);
strupper(user);
- dos_to_unix(user, True);
+ dos_to_unix(user);
if (strcmp(user, orig_username) != 0) {
ret = _Get_Pwnam(user);
@@ -271,9 +271,9 @@ struct passwd *Get_Pwnam(char *user,BOOL allow_change)
}
/* Try all combinations up to usernamelevel. */
- unix_to_dos(user, True);
+ unix_to_dos(user);
strlower(user);
- dos_to_unix(user, True);
+ dos_to_unix(user);
ret = uname_string_combinations(user, _Get_Pwnam, usernamelevel);
@@ -451,7 +451,7 @@ BOOL user_in_list(char *user,char *list)
while (next_token(&p,tok,LIST_SEP, sizeof(tok))) {
- DEBUG(10,("user_in_list: checking user |%s| in group |%s|\n", user, tok));
+ DEBUG(10,("user_in_list: checking user |%s| against |%s|\n", user, tok));
/*
* Check raw username.
@@ -524,7 +524,7 @@ BOOL user_in_list(char *user,char *list)
BOOL ret;
/* Check to see if name is a Windows group */
- if (winbind_lookup_name(tok, &g_sid, &name_type) && name_type == SID_NAME_DOM_GRP) {
+ if (winbind_lookup_name(NULL, tok, &g_sid, &name_type) && name_type == SID_NAME_DOM_GRP) {
/* Check if user name is in the Windows group */
ret = user_in_winbind_group_list(user, tok, &winbind_answered);
diff --git a/source/lib/util.c b/source/lib/util.c
index 9aad4f976aa..5d5fe195c0a 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -495,13 +495,13 @@ int set_blocking(int fd, BOOL set)
#endif
#endif
- if((val = fcntl(fd, F_GETFL, 0)) == -1)
+ if((val = sys_fcntl_long(fd, F_GETFL, 0)) == -1)
return -1;
if(set) /* Turn blocking on - ie. clear nonblock flag */
val &= ~FLAG_TO_SET;
else
val |= FLAG_TO_SET;
- return fcntl( fd, F_SETFL, val);
+ return sys_fcntl_long( fd, F_SETFL, val);
#undef FLAG_TO_SET
}
@@ -563,16 +563,16 @@ ssize_t transfer_file_internal(int infd, int outfd, size_t n, ssize_t (*read_fn)
SMB_OFF_T transfer_file(int infd,int outfd,SMB_OFF_T n)
{
- return (SMB_OFF_T)transfer_file_internal(infd, outfd, (size_t)n, read, write);
+ return (SMB_OFF_T)transfer_file_internal(infd, outfd, (size_t)n, sys_read, sys_write);
}
/*******************************************************************
Sleep for a specified number of milliseconds.
********************************************************************/
-void msleep(int t)
+void msleep(unsigned int t)
{
- int tdiff=0;
+ unsigned int tdiff=0;
struct timeval tval,t1,t2;
fd_set fds;
@@ -582,12 +582,23 @@ void msleep(int t)
while (tdiff < t) {
tval.tv_sec = (t-tdiff)/1000;
tval.tv_usec = 1000*((t-tdiff)%1000);
-
+
+ /* Never wait for more than 1 sec. */
+ if (tval.tv_sec > 1) {
+ tval.tv_sec = 1;
+ tval.tv_usec = 0;
+ }
+
FD_ZERO(&fds);
errno = 0;
sys_select_intr(0,&fds,NULL,NULL,&tval);
GetTimeOfDay(&t2);
+ if (t2.tv_sec < t1.tv_sec) {
+ /* Someone adjusted time... */
+ t1 = t2;
+ }
+
tdiff = TvalDiff(&t1,&t2);
}
}
@@ -793,15 +804,32 @@ struct in_addr *interpret_addr2(const char *str)
}
/*******************************************************************
- check if an IP is the 0.0.0.0
- ******************************************************************/
-BOOL zero_ip(struct in_addr ip)
+ Check if an IP is the 0.0.0.0
+ ******************************************************************/
+
+BOOL is_zero_ip(struct in_addr ip)
{
- uint32 a;
- putip((char *)&a,(char *)&ip);
- return(a == 0);
+ uint32 a;
+ putip((char *)&a,(char *)&ip);
+ return(a == 0);
}
+/*******************************************************************
+ Set an IP to 0.0.0.0
+ ******************************************************************/
+
+void zero_ip(struct in_addr *ip)
+{
+ static BOOL init;
+ static struct in_addr ipzero;
+
+ if (!init) {
+ ipzero = *interpret_addr2("0.0.0.0");
+ init = True;
+ }
+
+ *ip = ipzero;
+}
#if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT))
/******************************************************************
@@ -1279,11 +1307,9 @@ BOOL fcntl_lock(int fd, int op, SMB_OFF_T offset, SMB_OFF_T count, int type)
lock.l_len = count;
lock.l_pid = 0;
- errno = 0;
-
- ret = fcntl(fd,op,&lock);
+ ret = sys_fcntl_ptr(fd,op,&lock);
- if (errno != 0)
+ if (ret == -1 && errno != 0)
DEBUG(3,("fcntl_lock: fcntl lock gave errno %d (%s)\n",errno,strerror(errno)));
/* a lock query */
@@ -1333,6 +1359,25 @@ BOOL is_myname(char *s)
return(ret);
}
+/********************************************************************
+ Return only the first IP address of our configured interfaces
+ as a string
+ *******************************************************************/
+
+const char* get_my_primary_ip (void)
+{
+ static fstring ip_string;
+ int n;
+ struct iface_struct nics[MAX_INTERFACES];
+
+ if ((n=get_interfaces(nics, MAX_INTERFACES)) <= 0)
+ return NULL;
+
+ fstrcpy(ip_string, inet_ntoa(nics[0].ip));
+ return ip_string;
+}
+
+
BOOL is_myname_or_ipaddr(char *s)
{
char *ptr;
@@ -1710,11 +1755,10 @@ void *smb_xmalloc(size_t size)
return p;
}
-/*****************************************************************
+/**
Memdup with smb_panic on fail.
- *****************************************************************/
-
-void *xmemdup(const void *p, size_t size)
+**/
+void *smb_xmemdup(const void *p, size_t size)
{
void *p2;
p2 = smb_xmalloc(size);
@@ -1722,18 +1766,30 @@ void *xmemdup(const void *p, size_t size)
return p2;
}
-/*****************************************************************
+/**
strdup that aborts on malloc fail.
- *****************************************************************/
-
-char *xstrdup(const char *s)
+**/
+char *smb_xstrdup(const char *s)
{
char *s1 = strdup(s);
if (!s1)
- smb_panic("xstrdup: malloc fail\n");
+ smb_panic("smb_xstrdup: malloc fail\n");
return s1;
}
+/*
+ vasprintf that aborts on malloc fail
+*/
+int smb_xvasprintf(char **ptr, const char *format, va_list ap)
+{
+ int n;
+ n = vasprintf(ptr, format, ap);
+ if (n == -1 || ! *ptr) {
+ smb_panic("smb_xvasprintf: out of memory");
+ }
+ return n;
+}
+
/*****************************************************************
like strdup but for memory
*****************************************************************/
@@ -1780,6 +1836,26 @@ char *lock_path(char *name)
return fname;
}
+/*****************************************************************
+a useful function for returning a path in the Samba pid directory
+ *****************************************************************/
+char *pid_path(char *name)
+{
+ static pstring fname;
+
+ pstrcpy(fname,lp_piddir());
+ trim_string(fname,"","/");
+
+ if (!directory_exist(fname,NULL)) {
+ mkdir(fname,0755);
+ }
+
+ pstrcat(fname,"/");
+ pstrcat(fname,name);
+
+ return fname;
+}
+
/*******************************************************************
Given a filename - get its directory name
NB: Returned in static storage. Caveats:
@@ -1975,6 +2051,86 @@ BOOL unix_wild_match(char *pattern, char *string)
return unix_do_match(p2, s2) == 0;
}
+/*******************************************************************
+ free() a data blob
+*******************************************************************/
+
+static void free_data_blob(DATA_BLOB *d)
+{
+ if ((d) && (d->free)) {
+ SAFE_FREE(d->data);
+ }
+}
+
+/*******************************************************************
+ construct a data blob, must be freed with data_blob_free()
+ you can pass NULL for p and get a blank data blob
+*******************************************************************/
+
+DATA_BLOB data_blob(const void *p, size_t length)
+{
+ DATA_BLOB ret;
+
+ if (!length) {
+ ZERO_STRUCT(ret);
+ return ret;
+ }
+
+ if (p) {
+ ret.data = smb_xmemdup(p, length);
+ } else {
+ ret.data = smb_xmalloc(length);
+ }
+ ret.length = length;
+ ret.free = free_data_blob;
+ return ret;
+}
+
+/*******************************************************************
+ construct a data blob, using supplied TALLOC_CTX
+*******************************************************************/
+
+DATA_BLOB data_blob_talloc(TALLOC_CTX *mem_ctx, const void *p, size_t length)
+{
+ DATA_BLOB ret;
+
+ if (!p || !length) {
+ ZERO_STRUCT(ret);
+ return ret;
+ }
+
+ ret.data = talloc_memdup(mem_ctx, p, length);
+ if (ret.data == NULL)
+ smb_panic("data_blob_talloc: talloc_memdup failed.\n");
+
+ ret.length = length;
+ ret.free = NULL;
+ return ret;
+}
+
+/*******************************************************************
+free a data blob
+*******************************************************************/
+void data_blob_free(DATA_BLOB *d)
+{
+ if (d) {
+ if (d->free) {
+ (d->free)(d);
+ }
+ ZERO_STRUCTP(d);
+ }
+}
+
+/*******************************************************************
+clear a DATA_BLOB's contents
+*******************************************************************/
+void data_blob_clear(DATA_BLOB *d)
+{
+ if (d->data) {
+ memset(d->data, 0, d->length);
+ }
+}
+
#ifdef __INSURE__
/*******************************************************************
diff --git a/source/lib/util_file.c b/source/lib/util_file.c
index 526e8b01568..7ea9825ad1d 100644
--- a/source/lib/util_file.c
+++ b/source/lib/util_file.c
@@ -50,9 +50,10 @@ BOOL do_file_lock(int fd, int waitsecs, int type)
lock.l_pid = 0;
alarm(waitsecs);
+ /* Note we must *NOT* use sys_fcntl here ! JRA */
ret = fcntl(fd, SMB_F_SETLKW, &lock);
alarm(0);
- CatchSignal(SIGALRM, SIGNAL_CAST SIG_DFL);
+ CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
if (gotalarm) {
DEBUG(0, ("do_file_lock: failed to %s file.\n",
@@ -466,7 +467,7 @@ static char **file_lines_parse(char *p, size_t size, int *numlines, BOOL convert
if (convert) {
for (i = 0; ret[i]; i++)
- unix_to_dos(ret[i], True);
+ unix_to_dos(ret[i]);
}
return ret;
diff --git a/source/lib/util_seaccess.c b/source/lib/util_seaccess.c
index b8dc43dede4..b80ba6e8046 100644
--- a/source/lib/util_seaccess.c
+++ b/source/lib/util_seaccess.c
@@ -194,6 +194,31 @@ void se_map_generic(uint32 *access_mask, struct generic_mapping *mapping)
}
}
+/* Map standard access rights to object specific rights. This technique is
+ used to give meaning to assigning read, write, execute and all access to
+ objects. Each type of object has its own mapping of standard to object
+ specific access rights. */
+
+void se_map_standard(uint32 *access_mask, struct standard_mapping *mapping)
+{
+ uint32 old_mask = *access_mask;
+
+ if (*access_mask & READ_CONTROL_ACCESS) {
+ *access_mask &= ~READ_CONTROL_ACCESS;
+ *access_mask |= mapping->std_read;
+ }
+
+ if (*access_mask & (DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS)) {
+ *access_mask &= ~(DELETE_ACCESS|WRITE_DAC_ACCESS|WRITE_OWNER_ACCESS|SYNCHRONIZE_ACCESS);
+ *access_mask |= mapping->std_all;
+ }
+
+ if (old_mask != *access_mask) {
+ DEBUG(10, ("se_map_standard(): mapped mask 0x%08x to 0x%08x\n",
+ old_mask, *access_mask));
+ }
+}
+
/*****************************************************************************
Check access rights of a user against a security descriptor. Look at
each ACE in the security descriptor until an access denied ACE denies
@@ -221,7 +246,7 @@ BOOL se_access_check(SEC_DESC *sd, NT_USER_TOKEN *token,
*status = NT_STATUS_OK;
*acc_granted = 0;
- DEBUG(10,("se_access_check: requested access %x, for NT token with %u entries and first sid %s.\n",
+ DEBUG(10,("se_access_check: requested access 0x%08x, for NT token with %u entries and first sid %s.\n",
(unsigned int)acc_desired, (unsigned int)token->num_sids,
sid_to_string(sid_str, &token->user_sids[0])));
diff --git a/source/lib/util_sec.c b/source/lib/util_sec.c
index c559647bf45..af7edd60808 100644
--- a/source/lib/util_sec.c
+++ b/source/lib/util_sec.c
@@ -415,7 +415,7 @@ main()
#endif
/****************************************************************************
-Check if we are setuid root. Used in libsmb and smbpasswd parinoia checks.
+Check if we are setuid root. Used in libsmb and smbpasswd paranoia checks.
****************************************************************************/
BOOL is_setuid_root(void)
{
diff --git a/source/lib/util_sid.c b/source/lib/util_sid.c
index d9f7efe39b8..0004aa87033 100644
--- a/source/lib/util_sid.c
+++ b/source/lib/util_sid.c
@@ -1,6 +1,5 @@
/*
- Unix SMB/Netbios implementation.
- Version 1.9.
+ Unix SMB/CIFS implementation.
Samba utility functions
Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Luke Kenneth Caseson Leighton 1998-1999
@@ -23,7 +22,9 @@
#include "includes.h"
-
+/* NOTE! the global_sam_sid is the SID of our local SAM. This is only
+ equal to the domain SID when we are a DC, otherwise its our
+ workstation SID */
DOM_SID global_sam_sid;
extern pstring global_myname;
extern fstring global_myworkgroup;
@@ -61,7 +62,6 @@ static known_sid_users everyone_users[] = {
static known_sid_users creator_owner_users[] = {
{ 0, SID_NAME_ALIAS, "Creator Owner" },
- { 1, SID_NAME_ALIAS, "Creator Group" },
{0, (enum SID_NAME_USE)0, NULL}};
static known_sid_users nt_authority_users[] = {
@@ -360,6 +360,16 @@ char *sid_to_string(fstring sidstr_out, DOM_SID *sid)
return sidstr_out;
}
+/*
+ useful function for debug lines
+*/
+const char *sid_string_static(DOM_SID *sid)
+{
+ static fstring sid_str;
+ sid_to_string(sid_str, sid);
+ return sid_str;
+}
+
/*****************************************************************
Convert a string to a SID. Returns True on success, False on fail.
*****************************************************************/
@@ -370,21 +380,20 @@ BOOL string_to_sid(DOM_SID *sidout, const char *sidstr)
char *p, *q;
/* BIG NOTE: this function only does SIDS where the identauth is not >= 2^32 */
uint32 ia;
-
-
+
if (StrnCaseCmp( sidstr, "S-", 2)) {
DEBUG(0,("string_to_sid: Sid %s does not start with 'S-'.\n", sidstr));
return False;
}
memset((char *)sidout, '\0', sizeof(DOM_SID));
-
+
q = p = strdup(sidstr + 2);
if (p == NULL) {
DEBUG(0, ("string_to_sid: out of memory!\n"));
return False;
}
-
+
if (!next_token(&p, tok, "-", sizeof(tok))) {
DEBUG(0,("string_to_sid: Sid %s is not in a valid format.\n", sidstr));
SAFE_FREE(q);
@@ -422,8 +431,6 @@ BOOL string_to_sid(DOM_SID *sidout, const char *sidstr)
sid_append_rid(sidout, (uint32)strtoul(tok, NULL, 10));
}
- DEBUG(7,("string_to_sid: converted SID %s ok\n", sidstr));
-
SAFE_FREE(q);
return True;
}
@@ -509,12 +516,11 @@ DOM_SID *sid_dup(DOM_SID *src)
/*****************************************************************
Write a sid out into on-the-wire format.
*****************************************************************/
-
BOOL sid_linearize(char *outbuf, size_t len, DOM_SID *sid)
{
size_t i;
- if(len < sid_size(sid))
+ if (len < sid_size(sid))
return False;
SCVAL(outbuf,0,sid->sid_rev_num);
@@ -527,6 +533,45 @@ BOOL sid_linearize(char *outbuf, size_t len, DOM_SID *sid)
}
/*****************************************************************
+ parse a on-the-wire SID to a DOM_SID
+*****************************************************************/
+BOOL sid_parse(char *inbuf, size_t len, DOM_SID *sid)
+{
+ int i;
+ if (len < 8) return False;
+ sid->sid_rev_num = CVAL(inbuf, 0);
+ sid->num_auths = CVAL(inbuf, 1);
+ memcpy(sid->id_auth, inbuf+2, 6);
+ if (len < 8 + sid->num_auths*4) return False;
+ for (i=0;i<sid->num_auths;i++) {
+ sid->sub_auths[i] = IVAL(inbuf, 8+i*4);
+ }
+ return True;
+}
+
+
+/*****************************************************************
+ Compare the auth portion of two sids.
+*****************************************************************/
+int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2)
+{
+ int i;
+
+ if (sid1 == sid2) return 0;
+ if (!sid1) return -1;
+ if (!sid2) return 1;
+
+ if (sid1->sid_rev_num != sid2->sid_rev_num)
+ return sid1->sid_rev_num - sid2->sid_rev_num;
+
+ for (i = 0; i < 6; i++)
+ if (sid1->id_auth[i] != sid2->id_auth[i])
+ return sid1->id_auth[i] - sid2->id_auth[i];
+
+ return 0;
+}
+
+/*****************************************************************
Compare two sids.
*****************************************************************/
int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
@@ -538,28 +583,36 @@ int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2)
if (!sid2) return 1;
/* compare most likely different rids, first: i.e start at end */
+ if (sid1->num_auths != sid2->num_auths)
+ return sid1->num_auths - sid2->num_auths;
+
for (i = sid1->num_auths-1; i >= 0; --i)
if (sid1->sub_auths[i] != sid2->sub_auths[i])
return sid1->sub_auths[i] - sid2->sub_auths[i];
- if (sid1->num_auths != sid2->num_auths)
- return sid1->num_auths - sid2->num_auths;
+ return sid_compare_auth(sid1, sid2);
+}
- if (sid1->sid_rev_num != sid2->sid_rev_num)
- return sid1->sid_rev_num - sid2->sid_rev_num;
+/*****************************************************************
+see if 2 SIDs are in the same domain
+this just compares the leading sub-auths
+*****************************************************************/
+int sid_compare_domain(const DOM_SID *sid1, const DOM_SID *sid2)
+{
+ int n, i;
- for (i = 0; i < 6; i++)
- if (sid1->id_auth[i] != sid2->id_auth[i])
- return sid1->id_auth[i] - sid2->id_auth[i];
+ n = MIN(sid1->num_auths, sid2->num_auths);
- return 0;
-}
+ for (i = n-1; i >= 0; --i)
+ if (sid1->sub_auths[i] != sid2->sub_auths[i])
+ return sid1->sub_auths[i] - sid2->sub_auths[i];
+ return sid_compare_auth(sid1, sid2);
+}
/*****************************************************************
Compare two sids.
*****************************************************************/
-
BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
{
return sid_compare(sid1, sid2) == 0;
@@ -567,6 +620,53 @@ BOOL sid_equal(const DOM_SID *sid1, const DOM_SID *sid2)
/*****************************************************************
+ Check if the SID is our domain SID (S-1-5-21-x-y-z).
+*****************************************************************/
+BOOL sid_check_is_domain(const DOM_SID *sid)
+{
+ return sid_equal(sid, &global_sam_sid);
+}
+
+
+/*****************************************************************
+ Check if the SID is the builtin SID (S-1-5-32).
+*****************************************************************/
+BOOL sid_check_is_builtin(const DOM_SID *sid)
+{
+ return sid_equal(sid, &global_sid_Builtin);
+}
+
+
+/*****************************************************************
+ Check if the SID is our domain SID (S-1-5-21-x-y-z).
+*****************************************************************/
+BOOL sid_check_is_in_our_domain(const DOM_SID *sid)
+{
+ DOM_SID dom_sid;
+ uint32 rid;
+
+ sid_copy(&dom_sid, sid);
+ sid_split_rid(&dom_sid, &rid);
+
+ return sid_equal(&dom_sid, &global_sam_sid);
+}
+
+/*****************************************************************
+ Check if the SID is our domain SID (S-1-5-21-x-y-z).
+*****************************************************************/
+BOOL sid_check_is_in_builtin(const DOM_SID *sid)
+{
+ DOM_SID dom_sid;
+ uint32 rid;
+
+ sid_copy(&dom_sid, sid);
+ sid_split_rid(&dom_sid, &rid);
+
+ return sid_equal(&dom_sid, &global_sid_Builtin);
+}
+
+
+/*****************************************************************
Calculates size of a sid.
*****************************************************************/
@@ -593,7 +693,7 @@ BOOL non_mappable_sid(DOM_SID *sid)
if (sid_equal(&dom, &global_sid_Builtin))
return True;
- if (sid_equal(&dom, &global_sid_Creator_Owner_Domain))
+ if (sid_equal(&dom, &global_sid_Creator_Owner_Domain))
return True;
if (sid_equal(&dom, &global_sid_NT_Authority))
@@ -601,3 +701,20 @@ BOOL non_mappable_sid(DOM_SID *sid)
return False;
}
+
+/*
+ return the binary string representation of a DOM_SID
+ caller must free
+*/
+char *sid_binstring(DOM_SID *sid)
+{
+ char *buf, *s;
+ int len = sid_size(sid);
+ buf = malloc(len);
+ if (!buf) return NULL;
+ sid_linearize(buf, len, sid);
+ s = binary_string(buf, len);
+ free(buf);
+ return s;
+}
+
diff --git a/source/lib/util_sock.c b/source/lib/util_sock.c
index c3eb78109c2..4b5abbb5724 100644
--- a/source/lib/util_sock.c
+++ b/source/lib/util_sock.c
@@ -42,20 +42,19 @@ int smb_read_error = 0;
BOOL is_a_socket(int fd)
{
- int v,l;
- l = sizeof(int);
- return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
+ int v,l;
+ l = sizeof(int);
+ return(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&v, &l) == 0);
}
enum SOCK_OPT_TYPES {OPT_BOOL,OPT_INT,OPT_ON};
-typedef struct smb_socket_option
-{
- char *name;
- int level;
- int option;
- int value;
- int opttype;
+typedef struct smb_socket_option {
+ char *name;
+ int level;
+ int option;
+ int value;
+ int opttype;
} smb_socket_option;
smb_socket_option socket_options[] = {
@@ -97,6 +96,7 @@ smb_socket_option socket_options[] = {
/****************************************************************************
Print socket options.
****************************************************************************/
+
static void print_socket_options(int s)
{
int value, vlen = 4;
@@ -178,7 +178,7 @@ ssize_t read_udp_socket(int fd,char *buf,size_t len)
memset((char *)&sock,'\0',socklen);
memset((char *)&lastip,'\0',sizeof(lastip));
- ret = (ssize_t)recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
+ ret = (ssize_t)sys_recvfrom(fd,buf,len,0,(struct sockaddr *)&sock,&socklen);
if (ret <= 0) {
DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno)));
return(0);
@@ -223,10 +223,10 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma
if(fd == sslFd){
readret = SSL_read(ssl, buf + nread, maxcnt - nread);
}else{
- readret = read(fd, buf + nread, maxcnt - nread);
+ readret = sys_read(fd, buf + nread, maxcnt - nread);
}
#else /* WITH_SSL */
- readret = read(fd, buf + nread, maxcnt - nread);
+ readret = sys_read(fd, buf + nread, maxcnt - nread);
#endif /* WITH_SSL */
if (readret == 0) {
@@ -280,10 +280,10 @@ static ssize_t read_socket_with_timeout(int fd,char *buf,size_t mincnt,size_t ma
if(fd == sslFd){
readret = SSL_read(ssl, buf + nread, maxcnt - nread);
}else{
- readret = read(fd, buf + nread, maxcnt - nread);
+ readret = sys_read(fd, buf + nread, maxcnt - nread);
}
#else /* WITH_SSL */
- readret = read(fd, buf+nread, maxcnt-nread);
+ readret = sys_read(fd, buf+nread, maxcnt-nread);
#endif /* WITH_SSL */
if (readret == 0) {
@@ -335,10 +335,10 @@ ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned
if(fd == sslFd){
readret = SSL_read(ssl, buf + nread, maxcnt - nread);
}else{
- readret = read(fd, buf + nread, maxcnt - nread);
+ readret = sys_read(fd, buf + nread, maxcnt - nread);
}
#else /* WITH_SSL */
- readret = read(fd, buf + nread, maxcnt - nread);
+ readret = sys_read(fd, buf + nread, maxcnt - nread);
#endif /* WITH_SSL */
if (readret <= 0)
@@ -372,10 +372,10 @@ ssize_t read_with_timeout(int fd,char *buf,size_t mincnt,size_t maxcnt,unsigned
if(fd == sslFd){
readret = SSL_read(ssl, buf + nread, maxcnt - nread);
}else{
- readret = read(fd, buf + nread, maxcnt - nread);
+ readret = sys_read(fd, buf + nread, maxcnt - nread);
}
#else /* WITH_SSL */
- readret = read(fd, buf+nread, maxcnt-nread);
+ readret = sys_read(fd, buf+nread, maxcnt-nread);
#endif /* WITH_SSL */
if (readret <= 0)
@@ -394,12 +394,12 @@ send a keepalive packet (rfc1002)
BOOL send_keepalive(int client)
{
- unsigned char buf[4];
+ unsigned char buf[4];
- buf[0] = 0x85;
- buf[1] = buf[2] = buf[3] = 0;
+ buf[0] = 0x85;
+ buf[1] = buf[2] = buf[3] = 0;
- return(write_socket_data(client,(char *)buf,4) == 4);
+ return(write_socket_data(client,(char *)buf,4) == 4);
}
/****************************************************************************
@@ -408,38 +408,36 @@ BOOL send_keepalive(int client)
ssize_t read_data(int fd,char *buffer,size_t N)
{
- ssize_t ret;
- size_t total=0;
+ ssize_t ret;
+ size_t total=0;
- smb_read_error = 0;
+ smb_read_error = 0;
- while (total < N)
- {
+ while (total < N) {
#ifdef WITH_SSL
- if(fd == sslFd){
- ret = SSL_read(ssl, buffer + total, N - total);
- }else{
- ret = read(fd,buffer + total,N - total);
- }
+ if(fd == sslFd){
+ ret = SSL_read(ssl, buffer + total, N - total);
+ }else{
+ ret = sys_read(fd,buffer + total,N - total);
+ }
#else /* WITH_SSL */
- ret = read(fd,buffer + total,N - total);
+ ret = sys_read(fd,buffer + total,N - total);
#endif /* WITH_SSL */
- if (ret == 0)
- {
- DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
- smb_read_error = READ_EOF;
- return 0;
- }
- if (ret == -1)
- {
- DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
- smb_read_error = READ_ERROR;
- return -1;
- }
- total += ret;
- }
- return (ssize_t)total;
+ if (ret == 0) {
+ DEBUG(10,("read_data: read of %d returned 0. Error = %s\n", (int)(N - total), strerror(errno) ));
+ smb_read_error = READ_EOF;
+ return 0;
+ }
+
+ if (ret == -1) {
+ DEBUG(0,("read_data: read failure for %d. Error = %s\n", (int)(N - total), strerror(errno) ));
+ smb_read_error = READ_ERROR;
+ return -1;
+ }
+ total += ret;
+ }
+ return (ssize_t)total;
}
/****************************************************************************
@@ -456,10 +454,10 @@ ssize_t write_data(int fd,char *buffer,size_t N)
if(fd == sslFd){
ret = SSL_write(ssl,buffer + total,N - total);
} else {
- ret = write(fd,buffer + total,N - total);
+ ret = sys_write(fd,buffer + total,N - total);
}
#else /* WITH_SSL */
- ret = write(fd,buffer + total,N - total);
+ ret = sys_write(fd,buffer + total,N - total);
#endif /* WITH_SSL */
if (ret == -1) {
@@ -481,30 +479,30 @@ ssize_t write_data(int fd,char *buffer,size_t N)
ssize_t write_socket_data(int fd,char *buffer,size_t N)
{
- size_t total=0;
- ssize_t ret;
+ size_t total=0;
+ ssize_t ret;
- while (total < N)
- {
+ while (total < N) {
#ifdef WITH_SSL
- if(fd == sslFd){
- ret = SSL_write(ssl,buffer + total,N - total);
- }else{
- ret = send(fd,buffer + total,N - total, 0);
- }
+ if(fd == sslFd){
+ ret = SSL_write(ssl,buffer + total,N - total);
+ }else{
+ ret = sys_send(fd,buffer + total,N - total, 0);
+ }
#else /* WITH_SSL */
- ret = send(fd,buffer + total,N - total,0);
+ ret = sys_send(fd,buffer + total,N - total,0);
#endif /* WITH_SSL */
- if (ret == -1) {
- DEBUG(0,("write_socket_data: write failure. Error = %s\n", strerror(errno) ));
- return -1;
- }
- if (ret == 0) return total;
+ if (ret == -1) {
+ DEBUG(0,("write_socket_data: write failure. Error = %s\n", strerror(errno) ));
+ return -1;
+ }
+ if (ret == 0)
+ return (ssize_t)total;
- total += ret;
- }
- return (ssize_t)total;
+ total += ret;
+ }
+ return (ssize_t)total;
}
/****************************************************************************
@@ -513,17 +511,17 @@ write to a socket
ssize_t write_socket(int fd,char *buf,size_t len)
{
- ssize_t ret=0;
+ ssize_t ret=0;
- DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len));
- ret = write_socket_data(fd,buf,len);
+ DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len));
+ ret = write_socket_data(fd,buf,len);
- DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret));
- if(ret <= 0)
- DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
- (int)len, fd, strerror(errno) ));
+ DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret));
+ if(ret <= 0)
+ DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n",
+ (int)len, fd, strerror(errno) ));
- return(ret);
+ return(ret);
}
/****************************************************************************
@@ -536,30 +534,29 @@ timeout is in milliseconds.
static ssize_t read_smb_length_return_keepalive(int fd,char *inbuf,unsigned int timeout)
{
- ssize_t len=0;
- int msg_type;
- BOOL ok = False;
+ ssize_t len=0;
+ int msg_type;
+ BOOL ok = False;
- while (!ok)
- {
- if (timeout > 0)
- ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout) == 4);
- else
- ok = (read_data(fd,inbuf,4) == 4);
+ while (!ok) {
+ if (timeout > 0)
+ ok = (read_socket_with_timeout(fd,inbuf,4,4,timeout) == 4);
+ else
+ ok = (read_data(fd,inbuf,4) == 4);
- if (!ok)
- return(-1);
+ if (!ok)
+ return(-1);
- len = smb_len(inbuf);
- msg_type = CVAL(inbuf,0);
+ len = smb_len(inbuf);
+ msg_type = CVAL(inbuf,0);
- if (msg_type == 0x85)
- DEBUG(5,("Got keepalive packet\n"));
- }
+ if (msg_type == 0x85)
+ DEBUG(5,("Got keepalive packet\n"));
+ }
- DEBUG(10,("got smb length of %d\n",len));
+ DEBUG(10,("got smb length of %d\n",len));
- return(len);
+ return(len);
}
/****************************************************************************
@@ -571,23 +568,22 @@ timeout is in milliseconds.
ssize_t read_smb_length(int fd,char *inbuf,unsigned int timeout)
{
- ssize_t len;
+ ssize_t len;
- for(;;)
- {
- len = read_smb_length_return_keepalive(fd, inbuf, timeout);
+ for(;;) {
+ len = read_smb_length_return_keepalive(fd, inbuf, timeout);
- if(len < 0)
- return len;
+ if(len < 0)
+ return len;
- /* Ignore session keepalives. */
- if(CVAL(inbuf,0) != 0x85)
- break;
- }
+ /* Ignore session keepalives. */
+ if(CVAL(inbuf,0) != 0x85)
+ break;
+ }
- DEBUG(10,("read_smb_length: got smb length of %d\n",len));
+ DEBUG(10,("read_smb_length: got smb length of %d\n",len));
- return len;
+ return len;
}
/****************************************************************************
@@ -609,19 +605,35 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
len = read_smb_length_return_keepalive(fd,buffer,timeout);
if (len < 0) {
DEBUG(10,("receive_smb: length < 0!\n"));
- smb_read_error = READ_ERROR;
+
+ /*
+ * Correct fix. smb_read_error may have already been
+ * set. Only set it here if not already set. Global
+ * variables still suck :-). JRA.
+ */
+
+ if (smb_read_error == 0)
+ smb_read_error = READ_ERROR;
return(False);
}
/*
* A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
- * of header. Don't print the error if this fits.... JRA.
+ * of header. Don't print the error if this fits.... JRA.
*/
if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
DEBUG(0,("Invalid packet length! (%d bytes).\n",len));
if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) {
- smb_read_error = READ_ERROR;
+
+ /*
+ * Correct fix. smb_read_error may have already been
+ * set. Only set it here if not already set. Global
+ * variables still suck :-). JRA.
+ */
+
+ if (smb_read_error == 0)
+ smb_read_error = READ_ERROR;
return False;
}
}
@@ -629,7 +641,8 @@ BOOL receive_smb(int fd,char *buffer, unsigned int timeout)
if(len > 0) {
ret = read_data(fd,buffer+4,len);
if (ret != len) {
- smb_read_error = READ_ERROR;
+ if (smb_read_error == 0)
+ smb_read_error = READ_ERROR;
return False;
}
}
@@ -724,7 +737,7 @@ BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type)
len,inet_ntoa(ip),port,type==SOCK_DGRAM?"DGRAM":"STREAM"));
/* send it */
- ret = (sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
+ ret = (sys_sendto(out_fd,buf,len,0,(struct sockaddr *)&sock_out,sizeof(sock_out)) >= 0);
if (!ret)
DEBUG(0,("Packet send to %s(%d) failed ERRNO=%s\n",
@@ -1004,35 +1017,104 @@ char *get_socket_addr(int fd)
}
/*******************************************************************
- opens and connects to a unix pipe socket
+ Create protected unix domain socket.
+
+ some unixen cannot set permissions on a ux-dom-sock, so we
+ have to make sure that the directory contains the protection
+ permissions, instead.
******************************************************************/
-int open_pipe_sock(char *path)
+int create_pipe_sock(const char *socket_dir,
+ const char *socket_name,
+ mode_t dir_perms)
{
- int sock;
- struct sockaddr_un sa;
-
- sock = socket(AF_UNIX, SOCK_STREAM, 0);
-
- if (sock < 0)
- {
- DEBUG(0, ("unix socket open failed\n"));
- return sock;
- }
-
- ZERO_STRUCT(sa);
- sa.sun_family = AF_UNIX;
- safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1);
-
- DEBUG(10, ("socket open succeeded. file name: %s\n", sa.sun_path));
-
- if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0)
- {
- DEBUG(0,("socket connect to %s failed\n", sa.sun_path));
- close(sock);
- return -1;
- }
-
- return sock;
+ struct sockaddr_un sunaddr;
+ struct stat st;
+ int sock;
+ mode_t old_umask;
+ pstring path;
+
+ /* Create the socket directory or reuse the existing one */
+
+ if (lstat(socket_dir, &st) == -1) {
+
+ if (errno == ENOENT) {
+
+ /* Create directory */
+
+ if (mkdir(socket_dir, dir_perms) == -1) {
+ DEBUG(0, ("error creating socket directory "
+ "%s: %s\n", socket_dir,
+ strerror(errno)));
+ return -1;
+ }
+
+ } else {
+
+ DEBUG(0, ("lstat failed on socket directory %s: %s\n",
+ socket_dir, strerror(errno)));
+ return -1;
+ }
+
+ } else {
+
+ /* Check ownership and permission on existing directory */
+
+ if (!S_ISDIR(st.st_mode)) {
+ DEBUG(0, ("socket directory %s isn't a directory\n",
+ socket_dir));
+ return -1;
+ }
+
+ if ((st.st_uid != sec_initial_uid()) ||
+ ((st.st_mode & 0777) != dir_perms)) {
+ DEBUG(0, ("invalid permissions on socket directory "
+ "%s\n", socket_dir));
+ return -1;
+ }
+ }
+
+ /* Create the socket file */
+
+ old_umask = umask(0);
+
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+
+ if (sock == -1) {
+ perror("socket");
+ umask(old_umask);
+ return -1;
+ }
+
+ snprintf(path, sizeof(path), "%s/%s", socket_dir, socket_name);
+
+ unlink(path);
+ memset(&sunaddr, 0, sizeof(sunaddr));
+ sunaddr.sun_family = AF_UNIX;
+ safe_strcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)-1);
+
+ if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
+ DEBUG(0, ("bind failed on pipe socket %s: %s\n",
+ path,
+ strerror(errno)));
+ close(sock);
+ umask(old_umask);
+ return -1;
+ }
+
+ if (listen(sock, 5) == -1) {
+ DEBUG(0, ("listen failed on pipe socket %s: %s\n",
+ path,
+ strerror(errno)));
+ close(sock);
+ umask(old_umask);
+ return -1;
+ }
+
+ umask(old_umask);
+
+ /* Success! */
+
+ return sock;
}
/*******************************************************************
@@ -1127,4 +1209,3 @@ int sock_exec(const char *prog)
close(fd[1]);
return fd[0];
}
-
diff --git a/source/lib/util_str.c b/source/lib/util_str.c
index f5f9cc1fe44..a2b01a0fc7e 100644
--- a/source/lib/util_str.c
+++ b/source/lib/util_str.c
@@ -857,29 +857,29 @@ include the terminating zero.
char *safe_strcpy(char *dest,const char *src, size_t maxlength)
{
- size_t len;
+ size_t len;
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
- return NULL;
- }
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in safe_strcpy\n"));
+ return NULL;
+ }
- if (!src) {
- *dest = 0;
- return dest;
- }
+ if (!src) {
+ *dest = 0;
+ return dest;
+ }
- len = strlen(src);
+ len = strlen(src);
- if (len > maxlength) {
- DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
- (int)(len-maxlength), src));
- len = maxlength;
- }
+ if (len > maxlength) {
+ DEBUG(0,("ERROR: string overflow by %d in safe_strcpy [%.50s]\n",
+ (int)(len-maxlength), src));
+ len = maxlength;
+ }
- memcpy(dest, src, len);
- dest[len] = 0;
- return dest;
+ memcpy(dest, src, len);
+ dest[len] = 0;
+ return dest;
}
/*******************************************************************
@@ -889,29 +889,30 @@ include the terminating zero.
char *safe_strcat(char *dest, const char *src, size_t maxlength)
{
- size_t src_len, dest_len;
+ size_t src_len, dest_len;
- if (!dest) {
- DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
- return NULL;
- }
+ if (!dest) {
+ DEBUG(0,("ERROR: NULL dest in safe_strcat\n"));
+ return NULL;
+ }
- if (!src) {
- return dest;
- }
+ if (!src)
+ return dest;
- src_len = strlen(src);
- dest_len = strlen(dest);
+ src_len = strlen(src);
+ dest_len = strlen(dest);
- if (src_len + dest_len > maxlength) {
- DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
- (int)(src_len + dest_len - maxlength), src));
- src_len = maxlength - dest_len;
- }
+ if (src_len + dest_len > maxlength) {
+ DEBUG(0,("ERROR: string overflow by %d in safe_strcat [%.50s]\n",
+ (int)(src_len + dest_len - maxlength), src));
+ if (dest_len >= maxlength)
+ return dest;
+ src_len = maxlength - dest_len;
+ }
- memcpy(&dest[dest_len], src, src_len);
- dest[dest_len + src_len] = 0;
- return dest;
+ memcpy(&dest[dest_len], src, src_len);
+ dest[dest_len + src_len] = 0;
+ return dest;
}
/*******************************************************************
@@ -1309,3 +1310,25 @@ char *string_truncate(char *s, int length)
}
return s;
}
+
+/*
+ return a RFC2254 binary string representation of a buffer
+ used in LDAP filters
+ caller must free
+*/
+char *binary_string(char *buf, int len)
+{
+ char *s;
+ int i, j;
+ const char *hex = "0123456789ABCDEF";
+ s = malloc(len * 3 + 1);
+ if (!s) return NULL;
+ for (j=i=0;i<len;i++) {
+ s[j] = '\\';
+ s[j+1] = hex[((unsigned char)buf[i]) >> 4];
+ s[j+2] = hex[((unsigned char)buf[i]) & 0xF];
+ j += 3;
+ }
+ s[j] = 0;
+ return s;
+}
diff --git a/source/lib/util_unistr.c b/source/lib/util_unistr.c
index c044e8f248c..a2bd0cf4913 100644
--- a/source/lib/util_unistr.c
+++ b/source/lib/util_unistr.c
@@ -348,6 +348,20 @@ void unistr2_to_ascii(char *dest, const UNISTR2 *str, size_t maxlen)
*p = 0;
}
+/*******************************************************************
+ duplicate a UNISTR2 string into a null terminated char*
+ using a talloc context
+********************************************************************/
+char *unistr2_tdup(TALLOC_CTX *ctx, const UNISTR2 *str)
+{
+ char *s;
+ int maxlen = (str->uni_str_len+1)*4;
+ if (!str->buffer) return NULL;
+ s = (char *)talloc(ctx, maxlen); /* convervative */
+ if (!s) return NULL;
+ unistr2_to_ascii(s, str, maxlen);
+ return s;
+}
/*******************************************************************
Return a number stored in a buffer
@@ -492,20 +506,33 @@ char *dos_unistr(char *buf)
}
/*******************************************************************
+ returns the length in number of wide characters
+ ******************************************************************/
+int unistrlen(uint16 *s)
+{
+ int len;
+
+ if (!s)
+ return -1;
+
+ for (len=0; *s; s++,len++);
+
+ return len;
+}
+
+/*******************************************************************
Strcpy for unicode strings. returns length (in num of wide chars)
********************************************************************/
-int unistrcpy(char *dst, char *src)
+int unistrcpy(uint16 *dst, uint16 *src)
{
int num_wchars = 0;
- uint16 *wsrc = (uint16 *)src;
- uint16 *wdst = (uint16 *)dst;
- while (*wsrc) {
- *wdst++ = *wsrc++;
+ while (*src) {
+ *dst++ = *src++;
num_wchars++;
}
- *wdst = 0;
+ *dst = 0;
return num_wchars;
}
@@ -2053,6 +2080,11 @@ int rpcstr_pull(char* dest, void *src, int dest_len, int src_len, int flags)
{
if(dest_len==-1)
dest_len=MAXUNI-3;
- unistr_to_ascii(dest, src, dest_len - 1);
+
+ if (flags & STR_TERMINATE)
+ src_len = strlen_w(src)*2+2;
+
+ dest_len = MIN((src_len/2), (dest_len-1));
+ unistr_to_ascii(dest, src, dest_len);
return src_len;
}
diff --git a/source/lib/wins_srv.c b/source/lib/wins_srv.c
index c0cf64f751e..23700a026b5 100644
--- a/source/lib/wins_srv.c
+++ b/source/lib/wins_srv.c
@@ -184,11 +184,11 @@ struct in_addr wins_srv_ip( void )
if( now >= entry->mourning ) /* Found a live one. */
{
/* If we don't have the IP, look it up. */
- if( zero_ip( entry->ip_addr ) )
+ if( is_zero_ip( entry->ip_addr ) )
entry->ip_addr = *interpret_addr2( entry->server );
/* If we still don't have the IP then kill it, else return it. */
- if( zero_ip( entry->ip_addr ) )
+ if( is_zero_ip( entry->ip_addr ) )
entry->mourning = now + NECROMANCYCLE;
else
return( entry->ip_addr );
@@ -208,7 +208,7 @@ void wins_srv_died( struct in_addr boothill_ip )
{
list_entry *entry;
- if( zero_ip( boothill_ip ) )
+ if( is_zero_ip( boothill_ip ) )
{
DEBUG( 4, ("wins_srv_died(): Got request to mark zero IP down.\n") );
return;