diff options
Diffstat (limited to 'source/lib')
-rw-r--r-- | source/lib/access.c | 12 | ||||
-rw-r--r-- | source/lib/charcnv.c | 174 | ||||
-rw-r--r-- | source/lib/debug.c | 21 | ||||
-rw-r--r-- | source/lib/interface.c | 9 | ||||
-rw-r--r-- | source/lib/kanji.c | 349 | ||||
-rw-r--r-- | source/lib/messages.c | 128 | ||||
-rw-r--r-- | source/lib/pidfile.c | 6 | ||||
-rw-r--r-- | source/lib/replace.c | 42 | ||||
-rw-r--r-- | source/lib/snprintf.c | 34 | ||||
-rw-r--r-- | source/lib/substitute.c | 17 | ||||
-rw-r--r-- | source/lib/sysacls.c | 4 | ||||
-rw-r--r-- | source/lib/system.c | 134 | ||||
-rw-r--r-- | source/lib/talloc.c | 354 | ||||
-rw-r--r-- | source/lib/username.c | 16 | ||||
-rw-r--r-- | source/lib/util.c | 206 | ||||
-rw-r--r-- | source/lib/util_file.c | 5 | ||||
-rw-r--r-- | source/lib/util_seaccess.c | 27 | ||||
-rw-r--r-- | source/lib/util_sec.c | 2 | ||||
-rw-r--r-- | source/lib/util_sid.c | 163 | ||||
-rw-r--r-- | source/lib/util_sock.c | 361 | ||||
-rw-r--r-- | source/lib/util_str.c | 95 | ||||
-rw-r--r-- | source/lib/util_unistr.c | 46 | ||||
-rw-r--r-- | source/lib/wins_srv.c | 6 |
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; |