diff options
Diffstat (limited to 'source')
60 files changed, 2429 insertions, 5811 deletions
diff --git a/source/arcfour.c b/source/arcfour.c deleted file mode 100644 index a28d702a861..00000000000 --- a/source/arcfour.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - - a implementation of arcfour designed for use in the - SMB password change protocol based on the description - in 'Applied Cryptography', 2nd Edition. - - Copyright (C) Jeremy Allison 1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "arcfour.h" - -void set_arc4_key(unsigned char *data, int key_length, arc4_key *arckey) -{ - unsigned int i; - unsigned char j; - unsigned char tc; - unsigned char *s_box = &arckey->s_box[0]; - - arckey->index_i = 0; - arckey->index_j = 0; - for(i = 0; i < 256; i++) - s_box[i] = (unsigned char)i; - - j = 0; - for( i = 0; i < 256; i++) - { - j += (s_box[i] + data[i%key_length]); - tc = s_box[i]; - s_box[i] = s_box[j]; - s_box[j] = tc; - } -} - -void arc4(arc4_key *arckey, unsigned char *data_in, unsigned char *data_out, - int length) -{ - unsigned char tc; - int ind; - unsigned char i, j; - unsigned char t; - unsigned char *s_box = &arckey->s_box[0]; - - for( ind = 0; ind < length; ind++) - { - i = ++arckey->index_i; - j = arckey->index_j += s_box[i]; - tc = s_box[i]; - s_box[i] = s_box[j]; - s_box[j] = tc; - t = s_box[i] + s_box[j]; - *data_out++ = *data_in++ ^ s_box[t]; - } -} - -#if 0 -/* Test vector */ -unsigned char key_data[] = { 0x61, 0x8a, 0x63, 0xd2, 0xfb }; -unsigned char plaintext[] = { 0xdc, 0xee, 0x4c, 0xf9, 0x2c }; -unsigned char ciphertext[] = { 0xf1, 0x38, 0x29, 0xc9, 0xde }; - -int main(int argc, char *argv[]) -{ - unsigned char out[5]; - arc4_key key; - - set_arc4_key(key_data, 5, &key); - arc4(&key, plaintext, out, 5); - - if(memcmp(out, ciphertext, 5) ==0) - printf("Test ok !\n"); - else - printf("Test fail !\n"); - return 0; -} -#endif diff --git a/source/arcfour.h b/source/arcfour.h deleted file mode 100644 index 34a4e8f91be..00000000000 --- a/source/arcfour.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _ARC4_H_ -#define _ARC4_H_ - -/* - Unix SMB/Netbios implementation. - Version 1.9. - - a implementation of arcfour designed for use in the - SMB password change protocol based on the description - in 'Applied Cryptography', 2nd Edition. - - Copyright (C) Jeremy Allison 1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -typedef struct { - unsigned char s_box[256]; - unsigned char index_i; - unsigned char index_j; -} arc4_key; - -extern void set_arc4_key(unsigned char *data, int key_length, arc4_key *arckey); -extern void arc4(arc4_key *arckey, unsigned char *data_in, - unsigned char *data_out, int length); - -#endif /* _ARC4_H_ */ diff --git a/source/cgi.c b/source/cgi.c deleted file mode 100644 index 56c293985d6..00000000000 --- a/source/cgi.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - some simple CGI helper routines - Copyright (C) Andrew Tridgell 1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - - -#include "includes.h" - -#define MAX_VARIABLES 512 - -struct var { - char *name; - char *value; -}; - -static struct var variables[MAX_VARIABLES]; -static int num_variables; - - -static int grab_line(int *cl, char *line, int maxsize) -{ - int i = 0; - - while ((*cl)) { - int c = fgetc(stdin); - (*cl)--; - - if (c == EOF) { - (*cl) = 0; - break; - } - - if (c == '+') { - c = ' '; - } - - if (c == '\r') continue; - - if (strchr("\n&", c)) break; - - if (c == '%' && (*cl) >= 2) { - int c1, c2; - c1 = fgetc(stdin); - c2 = fgetc(stdin); - (*cl) -= 2; - if (c1 == EOF || c2 == EOF) break; - if (c1 >= '0' && c1 <= '9') - c1 = c1 - '0'; - else if (c1 >= 'A' && c1 <= 'F') - c1 = 10 + c1 - 'A'; - else if (c1 >= 'a' && c1 <= 'f') - c1 = 10 + c1 - 'a'; - else break; - - if (c2 >= '0' && c2 <= '9') - c2 = c2 - '0'; - else if (c2 >= 'A' && c2 <= 'F') - c2 = 10 + c2 - 'A'; - else if (c2 >= 'a' && c2 <= 'f') - c2 = 10 + c2 - 'a'; - else break; - - c = (c1<<4) | c2; - } - - line[i++] = c; - - if (i == maxsize) break; - } - - /* now unescape the line */ - - - line[i] = 0; - return 1; -} - - -/*************************************************************************** - load all the variables passed to the CGI program - ***************************************************************************/ -void cgi_load_variables(void) -{ - static pstring line; - char *p; - int len; - - if (!(p=getenv("CONTENT_LENGTH"))) return; - - len = atoi(p); - - if (len <= 0) return; - - - - while (len && grab_line(&len, line, sizeof(line)-1)) { - p = strchr(line,'='); - if (!p) continue; - - *p = 0; - - variables[num_variables].name = strdup(line); - variables[num_variables].value = strdup(p+1); - - if (!variables[num_variables].name || - !variables[num_variables].value) - continue; - -#if 0 - printf("%s=%s<br>\n", - variables[num_variables].name, - variables[num_variables].value); -#endif - - num_variables++; - if (num_variables == MAX_VARIABLES) break; - } - - fclose(stdin); -} - - -/*************************************************************************** - find a variable passed via CGI - ***************************************************************************/ -char *cgi_variable(char *name) -{ - int i; - - for (i=0;i<num_variables;i++) - if (strcmp(variables[i].name, name) == 0) - return variables[i].value; - return NULL; -} - - -/*************************************************************************** - return the value of a CGI boolean variable. - ***************************************************************************/ -int cgi_boolean(char *name, int def) -{ - char *p = cgi_variable(name); - - if (!p) return def; - - return strcmp(p, "1") == 0; -} diff --git a/source/client/client.c b/source/client/client.c index 275d03ddba2..4718db84ac0 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -143,8 +143,12 @@ extern int Client; #define USENMB +#ifdef KANJI extern int coding_system; -static BOOL setup_term_code (char *code) +#define CNV_LANG(s) (coding_system == DOSV_CODE?s:dos_to_unix(s, False)) +#define CNV_INPUT(s) (coding_system == DOSV_CODE?s:unix_to_dos(s, True)) +static BOOL +setup_term_code (char *code) { int new; new = interpret_coding_system (code, UNKNOWN_CODE); @@ -154,8 +158,10 @@ static BOOL setup_term_code (char *code) } return False; } +#else #define CNV_LANG(s) dos2unix_format(s,False) #define CNV_INPUT(s) unix2dos_format(s,True) +#endif /**************************************************************************** setup basics in a outgoing packet @@ -3303,11 +3309,15 @@ static BOOL send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setu int passlen = strlen(pass)+1; strcpy(pword,pass); +#ifdef SMB_PASSWD if (doencrypt && *pass) { DEBUG(3,("Using encrypted passwords\n")); passlen = 24; SMBencrypt((uchar *)pass,(uchar *)cryptkey,(uchar *)pword); } +#else + doencrypt = False; +#endif /* if in share level security then don't send a password now */ if (!(sec_mode & 1)) {strcpy(pword, "");passlen=1;} @@ -3418,10 +3428,12 @@ static BOOL send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setu fstring pword; strcpy(pword,pass); +#ifdef SMB_PASSWD if (doencrypt && *pass) { passlen=24; SMBencrypt((uchar *)pass,(uchar *)cryptkey,(uchar *)pword); } +#endif /* if in user level security then don't send a password now */ if ((sec_mode & 1)) { @@ -4380,6 +4392,10 @@ static void usage(char *pname) DEBUG(0,("Usage: %s service <password> [-p port] [-d debuglevel] [-l log] ", pname)); +#ifdef KANJI + DEBUG(0,("[-t termcode] ")); +#endif /* KANJI */ + DEBUG(0,("\nVersion %s\n",VERSION)); DEBUG(0,("\t-p port listen on the specified port\n")); DEBUG(0,("\t-d debuglevel set the debuglevel\n")); @@ -4395,7 +4411,9 @@ static void usage(char *pname) DEBUG(0,("\t-U username set the network username\n")); DEBUG(0,("\t-W workgroup set the workgroup name\n")); DEBUG(0,("\t-c command string execute semicolon separated commands\n")); +#ifdef KANJI DEBUG(0,("\t-t terminal code terminal i/o code {sjis|euc|jis7|jis8|junet|hex}\n")); +#endif /* KANJI */ DEBUG(0,("\t-T<c|x>IXgbNa command line tar\n")); DEBUG(0,("\t-D directory start from directory\n")); DEBUG(0,("\n")); @@ -4417,14 +4435,6 @@ static void usage(char *pname) BOOL message = False; extern char tar_type; static pstring servicesf = CONFIGFILE; - pstring term_code; - char *p; - -#ifdef KANJI - strcpy(term_code, KANJI); -#else /* KANJI */ - *term_code = 0; -#endif /* KANJI */ *query_host = 0; *base_directory = 0; @@ -4444,27 +4454,10 @@ static void usage(char *pname) umask(myumask); if (getenv("USER")) - { - strcpy(username,getenv("USER")); - - /* modification to support userid%passwd syntax in the USER var - 25.Aug.97, jdblair@uab.edu */ - - if ((p=strchr(username,'%'))) { - *p = 0; - strcpy(password,p+1); - got_pass = True; - memset(strchr(getenv("USER"),'%')+1,'X',strlen(password)); + strcpy(username,getenv("USER")); + strupper(username); } - strupper(username); - } - - /* modification to support PASSWD environmental var - 25.Aug.97, jdblair@uab.edu */ - - if (getenv("PASSWD")) - strcpy(password,getenv("PASSWD")); if (*username == 0 && getenv("LOGNAME")) { @@ -4513,6 +4506,9 @@ static void usage(char *pname) } } +#ifdef KANJI + setup_term_code (KANJI); +#endif while ((opt = getopt(argc, argv,"s:B:O:M:i:Nn:d:Pp:l:hI:EB:U:L:t:m:W:T:D:c:")) != EOF) switch (opt) @@ -4608,7 +4604,13 @@ static void usage(char *pname) strcpy(servicesf, optarg); break; case 't': - strcpy(term_code, optarg); +#ifdef KANJI + if (!setup_term_code (optarg)) { + DEBUG(0, ("%s: unknown terminal code name\n", optarg)); + usage (pname); + exit (1); + } +#endif break; default: usage(pname); @@ -4633,18 +4635,6 @@ static void usage(char *pname) fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf); } - codepage_initialise(lp_client_code_page()); - - if(lp_client_code_page() == KANJI_CODEPAGE) - { - if (!setup_term_code (term_code)) - { - DEBUG(0, ("%s: unknown terminal code name\n", optarg)); - usage (pname); - exit (1); - } - } - if (*workgroup == 0) strcpy(workgroup,lp_workgroup()); diff --git a/source/client/clientutil.c b/source/client/clientutil.c index d16e5a471fc..1b59946ff5b 100644 --- a/source/client/clientutil.c +++ b/source/client/clientutil.c @@ -441,11 +441,15 @@ BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setu int passlen = strlen(pass)+1; fstrcpy(pword,pass); +#ifdef SMB_PASSWD if (doencrypt && *pass) { DEBUG(5,("Using encrypted passwords\n")); passlen = 24; SMBencrypt((uchar *)pass,(uchar *)cryptkey,(uchar *)pword); } +#else + doencrypt = False; +#endif /* if in share level security then don't send a password now */ if (!(sec_mode & 1)) {fstrcpy(pword, "");passlen=1;} @@ -556,10 +560,12 @@ BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setu fstring pword; fstrcpy(pword,pass); +#ifdef SMB_PASSWD if (doencrypt && *pass) { passlen=24; SMBencrypt((uchar *)pass,(uchar *)cryptkey,(uchar *)pword); } +#endif /* if in user level security then don't send a password now */ if ((sec_mode & 1)) { diff --git a/source/client/clitar.c b/source/client/clitar.c index c085cd9e5a1..d5bca8c5bbb 100644 --- a/source/client/clitar.c +++ b/source/client/clitar.c @@ -90,7 +90,7 @@ static void unfixtarname(); Write a tar header to buffer ****************************************************************************/ static void writetarheader(int f, char *aname, int size, time_t mtime, - char *amode) + char *amode) { union hblock hb; int i, chk, l; @@ -99,21 +99,10 @@ static void writetarheader(int f, char *aname, int size, time_t mtime, memset(hb.dummy, 0, sizeof(hb.dummy)); l=strlen(aname); - if (l >= NAMSIZ) { - /* write a GNU tar style long header */ - char *b; - b = (char *)malloc(l+TBLOCK+100); - if (!b) { - DEBUG(0,("out of memory\n")); - exit(1); - } - writetarheader(f, "/./@LongLink", l+1, 0, " 0 \0"); - memset(b, 0, l+TBLOCK+100); - fixtarname(b, aname, l+1); - i = strlen(b)+1; - dotarbuf(f, b, TBLOCK*((i+(TBLOCK-1)/TBLOCK))); - free(b); - } + if (l >= NAMSIZ) + { + DEBUG(0, ("tar file %s name length exceeds NAMSIZ\n", aname)); + } /* use l + 1 to do the null too */ fixtarname(hb.dbuf.name, aname, (l >= NAMSIZ) ? NAMSIZ : l + 1); @@ -130,13 +119,8 @@ static void writetarheader(int f, char *aname, int size, time_t mtime, oct_it((long) size, 13, hb.dbuf.size); oct_it((long) mtime, 13, hb.dbuf.mtime); memcpy(hb.dbuf.chksum, " ", sizeof(hb.dbuf.chksum)); + hb.dbuf.linkflag='0'; memset(hb.dbuf.linkname, 0, NAMSIZ); - if (strcmp("/./@LongLink", aname) == 0) { - /* we're doing a GNU tar long filename */ - hb.dbuf.linkflag='L'; - } else { - hb.dbuf.linkflag='0'; - } for (chk=0, i=sizeof(hb.dummy), jp=hb.dummy; --i>=0;) chk+=(0xFF & *jp++); @@ -322,35 +306,27 @@ static void fixtarname(char *tptr, char *fp, int l) * to lovely unix /'s :-} */ *tptr++='.'; - if(lp_client_code_page() == KANJI_CODEPAGE) - { - while (l > 0) { - if (is_shift_jis (*fp)) { - *tptr++ = *fp++; - *tptr++ = *fp++; - l -= 2; - } else if (is_kana (*fp)) { - *tptr++ = *fp++; - l--; - } else if (*fp == '\\') { - *tptr++ = '/'; - fp++; - l--; - } else { - *tptr++ = *fp++; - l--; - } - } - } - else - { - while (l--) - { - *tptr=(*fp == '\\') ? '/' : *fp; - tptr++; +#ifdef KANJI + while (l > 0) { + if (is_shift_jis (*fp)) { + *tptr++ = *fp++; + *tptr++ = *fp++; + l -= 2; + } else if (is_kana (*fp)) { + *tptr++ = *fp++; + l--; + } else if (*fp == '\\') { + *tptr++ = '/'; fp++; + l--; + } else { + *tptr++ = *fp++; + l--; } } +#else + while (l--) { *tptr=(*fp == '\\') ? '/' : *fp; tptr++; fp++; } +#endif } /**************************************************************************** @@ -1074,7 +1050,7 @@ static void do_atar(char *rname,char *lname,file_info *finfo1) * write out in 512 byte intervals */ if (dotarbuf(tarhandle,dataptr,datalen) != datalen) { - DEBUG(0,("Error writing to tar file - %s\n", strerror(errno))); + DEBUG(0,("Error writing local file\n")); break; } @@ -1094,7 +1070,7 @@ static void do_atar(char *rname,char *lname,file_info *finfo1) { DEBUG(0, ("Didn't get entire file. size=%d, nread=%d\n", finfo.size, nread)); if (padit(inbuf, BUFFER_SIZE, finfo.size - nread)) - DEBUG(0,("Error writing tar file - %s\n", strerror(errno))); + DEBUG(0,("Error writing local file\n")); } /* round tar file to nearest block */ @@ -1227,35 +1203,27 @@ static void unfixtarname(char *tptr, char *fp, int l) if (*fp == '.') fp++; if (*fp == '\\' || *fp == '/') fp++; - if(lp_client_code_page() == KANJI_CODEPAGE) - { - while (l > 0) { - if (is_shift_jis (*fp)) { - *tptr++ = *fp++; - *tptr++ = *fp++; - l -= 2; - } else if (is_kana (*fp)) { - *tptr++ = *fp++; - l--; - } else if (*fp == '/') { - *tptr++ = '\\'; - fp++; - l--; - } else { - *tptr++ = *fp++; - l--; - } - } - } - else - { - while (l--) - { - *tptr=(*fp == '/') ? '\\' : *fp; - tptr++; +#ifdef KANJI + while (l > 0) { + if (is_shift_jis (*fp)) { + *tptr++ = *fp++; + *tptr++ = *fp++; + l -= 2; + } else if (is_kana (*fp)) { + *tptr++ = *fp++; + l--; + } else if (*fp == '/') { + *tptr++ = '\\'; fp++; + l--; + } else { + *tptr++ = *fp++; + l--; } } +#else + while (l--) { *tptr=(*fp == '/') ? '\\' : *fp; tptr++; fp++; } +#endif } static void do_tarput() @@ -1761,8 +1729,7 @@ int tar_parseargs(int argc, char *argv[], char *Optarg, int Optind) if ((tar_type=='x' && (tarhandle = open(argv[Optind], O_RDONLY)) == -1) || (tar_type=='c' && (tarhandle=creat(argv[Optind], 0644)) < 0)) { - DEBUG(0,("Error opening local file %s - %s\n", - argv[Optind], strerror(errno))); + DEBUG(0,("Error opening local file %s\n",argv[Optind])); return(0); } } diff --git a/source/codepages/codepage_def.437 b/source/codepages/codepage_def.437 deleted file mode 100644 index d357c074e44..00000000000 --- a/source/codepages/codepage_def.437 +++ /dev/null @@ -1,70 +0,0 @@ -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# - -# Codepage definition file for IBM Code Page 437 - MS-DOS Latin US -# defines lower->upper mapping. -# Written by Jeremy Allison <jallison@whistle.com> - -# The columns are : -# lower upper map upper to lower map lower to upper -# - 0x87 0x80 True True - 0x81 0x9A True True - 0x82 0x90 True True - 0x83 0x41 True False - 0x84 0x8E True True - 0x85 0x41 True False - 0x86 0x8F True True - 0x88 0x45 True False - 0x89 0x45 True False - 0x8A 0x45 True False - 0x8B 0x49 True False - 0x8C 0x49 True False - 0x8D 0x49 True False - 0x91 0x92 True True - 0x93 0x4F True False - 0x94 0x99 True True - 0x95 0x4F True False - 0x96 0x55 True False - 0x97 0x55 True False - 0x9B 0 False False - 0x9C 0 False False - 0x9D 0 False False - 0xA0 0x41 True False - 0xA1 0x49 True False - 0xA2 0x4F True False - 0xA3 0x55 True False - 0xA4 0xA5 True True - 0xA8 0 False False - 0xAD 0 False False - 0xAE 0 False False - 0xAF 0 False False - 0xE0 0 False False - 0xE1 0 False False - 0xE2 0 False False - 0xE3 0 False False - 0xE4 0 False False - 0xE5 0 False False - 0xE6 0 False False - 0xE7 0 False False - 0xE8 0 False False - 0xE9 0 False False - 0xEA 0 False False - 0xEB 0 False False - 0xEC 0 False False - 0xED 0 False False - 0xEE 0 False False - 0xEF 0 False False diff --git a/source/codepages/codepage_def.850 b/source/codepages/codepage_def.850 deleted file mode 100644 index e2466a707af..00000000000 --- a/source/codepages/codepage_def.850 +++ /dev/null @@ -1,54 +0,0 @@ -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# - -# Codepage definition file for IBM Code Page 850 - MS-DOS Latin 1 -# defines lower->upper mapping. -# Written by Jeremy Allison (jallison@whistle.com) - -# The columns are : -# lower upper map upper to lower map lower to upper -# - 0x85 0xB7 True True - 0xA0 0xB5 True True - 0x83 0xB6 True True - 0xC6 0xC7 True True - 0x84 0x8E True True - 0x86 0x8F True True - 0x91 0x92 True True - 0x87 0x80 True True - 0x8A 0xD4 True True - 0x82 0x90 True True - 0x88 0xD2 True True - 0x89 0xD3 True True - 0x8D 0xDE True True - 0xA1 0xD6 True True - 0x8C 0xD7 True True - 0x8B 0xD8 True True - 0xD0 0xD1 True True - 0xA4 0xA5 True True - 0x95 0xE3 True True - 0xA2 0xE0 True True - 0x93 0xE2 True True - 0xE4 0xE5 True True - 0x94 0x99 True True - 0x9B 0x9D True True - 0x97 0xEB True True - 0xA3 0xE9 True True - 0x96 0xEA True True - 0x81 0x9A True True - 0xEC 0xED True True - 0xE7 0xE8 True True - 0x9C 0 False False diff --git a/source/codepages/codepage_def.852 b/source/codepages/codepage_def.852 deleted file mode 100644 index ed1423428ca..00000000000 --- a/source/codepages/codepage_def.852 +++ /dev/null @@ -1,63 +0,0 @@ -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# - -# Codepage definition file for IBM Code Page 852 - MS-DOS Latin 2 -# defines lower->upper mapping. -# Written by Leos Bitto <bitto@altec.cz> - -# The columns are : -# lower upper map upper to lower map lower to upper -# - 0x81 0x9A True True - 0x82 0x90 True True - 0x83 0xB6 True True - 0x84 0x8E True True - 0x85 0xDE True True - 0x86 0x8F True True - 0x87 0x80 True True - 0x88 0x9D True True - 0x89 0xD3 True True - 0x8B 0x8A True True - 0x8C 0xD7 True True - 0x92 0x91 True True - 0x93 0xE2 True True - 0x94 0x99 True True - 0x96 0x95 True True - 0x98 0x97 True True - 0x9C 0x9B True True - 0x9F 0xAC True True - 0xA0 0xB5 True True - 0xA1 0xD6 True True - 0xA2 0xE0 True True - 0xA3 0xE9 True True - 0xA5 0xA4 True True - 0xA7 0xA6 True True - 0xA9 0xA8 True True - 0xAB 0x8D True True - 0xAD 0xB8 True True - 0xBE 0xBD True True - 0xC7 0xC6 True True - 0xD0 0xD1 True True - 0xD4 0xD2 True True - 0xD8 0xB7 True True - 0xE4 0xE3 True True - 0xE5 0xD5 True True - 0xE7 0xE6 True True - 0xEA 0xE8 True True - 0xEC 0xED True True - 0xEE 0xDD True True - 0xFB 0xEB True True - 0xFD 0xFC True True diff --git a/source/codepages/codepage_def.932 b/source/codepages/codepage_def.932 deleted file mode 100644 index 8d9ff631fba..00000000000 --- a/source/codepages/codepage_def.932 +++ /dev/null @@ -1,24 +0,0 @@ -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -# - -# Codepage definition file for IBM Code Page 932 - MS-DOS Japanese SJIS -# defines lower->upper mapping. -# Written by Jeremy Allison <jallison@whistle.com> - -# The columns are : -# lower upper map upper to lower map lower to upper -# -# This file is intentionaly empty - no mappings are done.
\ No newline at end of file diff --git a/source/include/charset.h b/source/include/charset.h index fb184897c07..5f5e2016ee1 100644 --- a/source/include/charset.h +++ b/source/include/charset.h @@ -63,13 +63,3 @@ extern void charset_initialise(void); #define issafe(c) (isalnum((c&0xff)) || strchr("-._",c)) #endif -/* Dynamic codepage files defines. */ - -/* Version id for dynamically loadable codepage files. */ -#define CODEPAGE_FILE_VERSION_ID 0x1 -/* Version 1 codepage file header size. */ -#define CODEPAGE_HEADER_SIZE 8 -/* Offsets for codepage file header entries. */ -#define CODEPAGE_VERSION_OFFSET 0 -#define CODEPAGE_CLIENT_CODEPAGE_OFFSET 2 -#define CODEPAGE_LENGTH_OFFSET 4 diff --git a/source/include/includes.h b/source/include/includes.h index 2329553d234..4e48e87a7c1 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -563,7 +563,9 @@ char *mktemp(char *); /* No standard include */ #define USE_SETSID #define USE_SETRES #define DEFAULT_PRINTING PRINT_HPUX -#define SIGCLD_IGNORE +/* Ken Weiss <krweiss@ucdavis.edu> tells us that SIGCLD_IGNORE is + not good for HPUX */ +/* #define SIGCLD_IGNORE */ #endif /* HPUX */ @@ -1194,10 +1196,6 @@ it works and getting lots of bug reports */ #define QSORT_CAST (int (*)()) #endif -#ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK 0x7f000001 -#endif /* INADDR_LOOPBACK */ - /* this is a rough check to see if this machine has a lstat() call. it is not guaranteed to work */ #if !(defined(S_ISLNK) || defined(S_IFLNK)) diff --git a/source/include/kanji.h b/source/include/kanji.h index cf303659208..865ac3b2c90 100644 --- a/source/include/kanji.h +++ b/source/include/kanji.h @@ -27,6 +27,8 @@ #ifndef _KANJI_H_ #define _KANJI_H_ +#ifdef KANJI + /* FOR SHIFT JIS CODE */ #define is_shift_jis(c) \ ((0x81 <= ((unsigned char) (c)) && ((unsigned char) (c)) <= 0x9f) \ @@ -105,8 +107,16 @@ #else /* not _KANJI_C_ */ -extern char *(*_dos_to_unix)(char *str, BOOL overwrite); -extern char *(*_unix_to_dos)(char *str, BOOL overwrite); +extern char* (*_dos_to_unix) (const char *str, BOOL overwrite); +extern char* (*_unix_to_dos) (const char *str, BOOL overwrite); + +#define unix_to_dos (*_unix_to_dos) +#define dos_to_unix (*_dos_to_unix) + +extern char *sj_strtok (char *s1, const char *s2); +extern char *sj_strchr (const char *s, int c); +extern char *sj_strrchr (const char *s, int c); +extern char *sj_strstr (const char *s1, const char *s2); #define strchr sj_strchr #define strrchr sj_strrchr @@ -127,7 +137,11 @@ extern char *(*_unix_to_dos)(char *str, BOOL overwrite); int interpret_coding_system (char *str, int def); +#else + #define unix_to_dos(x,y) unix2dos_format(x,y) #define dos_to_unix(x,y) dos2unix_format(x,y) +#endif /* not KANJI */ + #endif /* _KANJI_H_ */ diff --git a/source/include/local.h b/source/include/local.h index 3ce75eeb4e7..f5f2c318180 100644 --- a/source/include/local.h +++ b/source/include/local.h @@ -43,7 +43,7 @@ #define WORDMAX 0xFFFF /* the maximum password length before we declare a likely attack */ -#define MAX_PASSWORD_LENGTH 200 +#define MAX_PASS_LEN 200 /* separators for lists */ #define LIST_SEP " \t,;:\n\r" @@ -159,9 +159,4 @@ /* the directory to sit in when idle */ /* #define IDLE_DIR "/" */ -/* Timout (in seconds) to wait for an oplock breal - message to return. */ - -#define OPLOCK_BREAK_TIMEOUT 30 - #endif diff --git a/source/include/proto.h b/source/include/proto.h index 8818b9b5274..d7cbc4cc4c4 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -114,10 +114,6 @@ int reply_trans(char *inbuf,char *outbuf); /*The following definitions come from kanji.c */ -char *sj_strtok(char *s1, char *s2); -char *sj_strstr(char *s1, char *s2); -char *sj_strchr (char *s, int c); -char *sj_strrchr(char *s, int c); int interpret_coding_system(char *str, int def); /*The following definitions come from loadparm.c */ @@ -183,7 +179,6 @@ int lp_maxmux(void); int lp_maxpacket(void); int lp_keepalive(void); int lp_passwordlevel(void); -int lp_usernamelevel(void); int lp_readsize(void); int lp_shmem_size(void); int lp_shmem_hash_size(void); @@ -248,7 +243,6 @@ BOOL lp_map_archive(int ); BOOL lp_locking(int ); BOOL lp_strict_locking(int ); BOOL lp_share_modes(int ); -BOOL lp_oplocks(int ); BOOL lp_onlyuser(int ); BOOL lp_manglednames(int ); BOOL lp_widelinks(int ); @@ -257,7 +251,6 @@ BOOL lp_syncalways(int ); BOOL lp_map_system(int ); BOOL lp_delete_readonly(int ); BOOL lp_fake_oplocks(int ); -BOOL lp_recursive_veto_delete(int ); int lp_create_mode(int ); int lp_force_create_mode(int ); int lp_dir_mode(int ); @@ -270,20 +263,14 @@ BOOL lp_add_home(char *pszHomename, int iDefaultService, char *pszHomedir); int lp_add_service(char *pszService, int iDefaultService); BOOL lp_add_printer(char *pszPrintername, int iDefaultService); BOOL lp_file_list_changed(void); -BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue); -int lp_next_parameter(int snum, int *i, char *label, - char *value, int allparameters); BOOL lp_snum_ok(int iService); BOOL lp_loaded(void); void lp_killunused(BOOL (*snumused)(int )); BOOL lp_load(char *pszFname,BOOL global_only); int lp_numservices(void); -void lp_dump(FILE *f); +void lp_dump(void); int lp_servicenumber(char *pszServiceName); char *volume_label(int snum); -void lp_rename_service(int snum, char *new_name); -void lp_remove_service(int snum); -void lp_copy_service(int snum, char *new_name); int lp_default_server_announce(void); int lp_major_announce_version(void); int lp_minor_announce_version(void); @@ -300,15 +287,13 @@ BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token tok int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode, min_share_mode_entry **old_shares); void del_share_mode(share_lock_token token, int fnum); -BOOL set_share_mode(share_lock_token token, int fnum, uint16 port, uint16 op_type); -BOOL remove_share_oplock(int fnum, share_lock_token token); +BOOL set_share_mode(share_lock_token token, int fnum); BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok); BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token token); int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode, min_share_mode_entry **old_shares); void del_share_mode(share_lock_token token, int fnum); -BOOL set_share_mode(share_lock_token token,int fnum, uint16 port, uint16 op_type); -BOOL remove_share_oplock(int fnum, share_lock_token token); +BOOL set_share_mode(share_lock_token token,int fnum); /*The following definitions come from mangle.c */ @@ -322,7 +307,6 @@ BOOL name_map_mangle(char *OutName,BOOL need83,int snum); /*The following definitions come from md4.c */ -void mdfour(unsigned char *out, unsigned char *in, int n); /*The following definitions come from message.c */ @@ -362,6 +346,20 @@ struct browse_cache_record *add_browser_entry(char *name, int type, char *wg, struct in_addr ip, BOOL local); void do_browser_lists(time_t t); +/*The following definitions come from nameconf.c */ + +int get_num_workgroups(void); +int conf_workgroup_name_to_token(char *workgroup_name,char *default_name); +char *conf_workgroup_name(int token); +int conf_should_workgroup_member(int token); +int conf_should_local_master(int token); +int conf_should_domain_master(int token); +char *conf_browsing_alias(int token); +char *conf_browsing_alias_comment(int token); +char *conf_alias_to_workgroup(char *alias); +int conf_alias_to_token(char *alias); +void read_smbbrowse_conf(char *default_name); + /*The following definitions come from namedbname.c */ void set_samba_nb_type(void); @@ -543,7 +541,6 @@ BOOL reload_services(BOOL test); /*The following definitions come from nmblib.c */ -char *lookup_opcode_name( int opcode ); void debug_nmb_packet(struct packet_struct *p); char *namestr(struct nmb_name *n); void free_nmb_packet(struct nmb_packet *nmb); @@ -704,13 +701,14 @@ BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_pa int disk_free(char *path,int *bsize,int *dfree,int *dsize); int sys_disk_free(char *path,int *bsize,int *dfree,int *dsize); BOOL check_name(char *name,int cnum); +int fd_attempt_open(char *fname, int flags, int mode); +void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr); +int fd_attempt_close(file_fd_struct *fd_ptr); void sync_file(int fnum); -void close_file(int fnum); +void close_file(int fnum, int normal_close); BOOL check_file_sharing(int cnum,char *fname); -int check_share_mode( min_share_mode_entry *share, int deny_mode, char *fname, - BOOL fcbopen, int *flags); void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, - int mode,int oplock_request, int *Access,int *action); + int mode,int *Access,int *action); int seek_file(int fnum,uint32 pos); int read_file(int fnum,char *data,uint32 pos,int n); int write_file(int fnum,char *data,int n); @@ -719,9 +717,6 @@ int find_service(char *service); int cached_error_packet(char *inbuf,char *outbuf,int fnum,int line); int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int line); int error_packet(char *inbuf,char *outbuf,int error_class,uint32 error_code,int line); -BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval); -BOOL request_oplock_break(min_share_mode_entry *share_entry, - uint32 dev, uint32 inode); BOOL snum_used(int snum); BOOL reload_services(BOOL test); int setup_groups(char *user, int uid, int gid, int *p_ngroups, @@ -751,7 +746,7 @@ smb_shm_offset_t smb_shm_alloc(int size); BOOL smb_shm_free(smb_shm_offset_t offset); smb_shm_offset_t smb_shm_get_userdef_off(void); BOOL smb_shm_set_userdef_off(smb_shm_offset_t userdef_off); -void *smb_shm_offset2addr(smb_shm_offset_t offset); +void * smb_shm_offset2addr(smb_shm_offset_t offset); smb_shm_offset_t smb_shm_addr2offset(void *addr); BOOL smb_shm_lock_hash_entry( unsigned int entry); BOOL smb_shm_unlock_hash_entry( unsigned int entry ); @@ -759,13 +754,13 @@ BOOL smb_shm_get_usage(int *bytes_free, int *bytes_used, int *bytes_overhead); -/*The following definitions come from smbdes.c */ - -void E_P16(unsigned char *p14,unsigned char *p16); -void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24); - /*The following definitions come from smbencrypt.c */ +void str_to_key(uchar *str,uchar *key); +void D1(uchar *k, uchar *d, uchar *out); +void E1(uchar *k, uchar *d, uchar *out); +void E_P16(uchar *p14,uchar *p16); +void E_P24(uchar *p21, uchar *c8, uchar *p24); void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24); void E_md4hash(uchar *passwd, uchar *p16); void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24); @@ -852,6 +847,8 @@ BOOL become_guest(void); BOOL become_user(int cnum, uint16 vuid); BOOL unbecome_user(void ); int smbrun(char *cmd,char *outfile,BOOL shared); +void become_root(int save_dir) ; +void unbecome_root(int restore_dir); /*The following definitions come from username.c */ @@ -882,10 +879,10 @@ time_t file_modtime(char *fname); BOOL directory_exist(char *dname,struct stat *st); uint32 file_size(char *file_name); char *attrib_string(int mode); -int StrCaseCmp(char *s, char *t); -int StrnCaseCmp(char *s, char *t, int n); -BOOL strequal(char *s1, char *s2); -BOOL strnequal(char *s1,char *s2,int n); +int StrCaseCmp(const char *s, const char *t); +int StrnCaseCmp(const char *s, const char *t, int n); +BOOL strequal(const char *s1, const char *s2); +BOOL strnequal(const char *s1,const char *s2,int n); BOOL strcsequal(char *s1,char *s2); void strlower(char *s); void strupper(char *s); @@ -928,12 +925,7 @@ int read_data(int fd,char *buffer,int N); int write_data(int fd,char *buffer,int N); int transfer_file(int infd,int outfd,int n,char *header,int headlen,int align); int read_smb_length(int fd,char *inbuf,int timeout); -BOOL receive_smb(int fd,char *buffer, int timeout); -BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout); -BOOL push_local_message(char *buf, int msg_len); -BOOL receive_message_or_smb(int smbfd, int oplock_fd, - char *buffer, int buffer_len, - int timeout, BOOL *got_smb); +BOOL receive_smb(int fd,char *buffer,int timeout); BOOL send_smb(int fd,char *buffer); char *name_ptr(char *buf,int ofs); int name_extract(char *buf,int ofs,char *name); @@ -983,8 +975,21 @@ void free_namearray(name_compare_entry *name_array); BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type); int file_lock(char *name,int timeout); void file_unlock(int fd); -BOOL is_myname(char *s); +BOOL is_myname(const char *s); void set_remote_arch(enum remote_arch_types type); enum remote_arch_types get_remote_arch(); void fstrcpy(char *dest, char *src); void pstrcpy(char *dest, char *src); + +/*The following definitions come from vt_mode.c */ + +int VT_Check(char *buffer); +int VT_Start_utmp(void); +int VT_Stop_utmp(void); +void VT_AtExit(void); +void VT_SigCLD(int sig); +void VT_SigEXIT(int sig); +int VT_Start(void); +int VT_Output(char *Buffer); +int VT_Input(char *Buffer,int Size); +void VT_Process(void); diff --git a/source/include/smb.h b/source/include/smb.h index 66da2099c77..b55c180f361 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -330,7 +330,6 @@ typedef struct BOOL share_mode; BOOL print_file; BOOL modified; - BOOL granted_oplock; char *name; } files_struct; @@ -453,10 +452,6 @@ typedef struct { smb_shm_offset_t next_share_mode_entry; int pid; -#ifdef USE_OPLOCKS - uint16 op_port; - uint16 op_type; -#endif /* USE_OPLOCKS */ int share_mode; struct timeval time; } share_mode_entry; @@ -465,10 +460,6 @@ typedef struct typedef struct { int pid; -#ifdef USE_OPLOCKS - uint16 op_port; - uint16 op_type; -#endif /* USE_OPLOCKS */ int share_mode; struct timeval time; } min_share_mode_entry; @@ -493,48 +484,8 @@ struct connect_record time_t start; }; -#ifndef LOCKING_VERSION -#ifdef USE_OPLOCKS -#define LOCKING_VERSION 4 -#else /* USE_OPLOCKS */ -#define LOCKING_VERSION 3 -#endif /* USE_OPLOCKS */ -#endif /* LOCKING_VERSION */ - -#if !defined(FAST_SHARE_MODES) -/* - * Defines for slow share modes. - */ - -/* - * Locking file header lengths & offsets. - */ -#define SMF_VERSION_OFFSET 0 -#define SMF_NUM_ENTRIES_OFFSET 4 -#define SMF_FILENAME_LEN_OFFSET 8 -#define SMF_HEADER_LENGTH 10 - -#ifdef USE_OPLOCKS -#define SMF_ENTRY_LENGTH 20 -#else /* USE_OPLOCKS */ -#define SMF_ENTRY_LENGTH 16 -#endif /* USE_OPLOCKS */ - -/* - * Share mode record offsets. - */ - -#define SME_SEC_OFFSET 0 -#define SME_USEC_OFFSET 4 -#define SME_SHAREMODE_OFFSET 8 -#define SME_PID_OFFSET 12 - -#ifdef USE_OPLOCKS -#define SME_PORT_OFFSET 16 -#define SME_OPLOCK_TYPE_OFFSET 18 -#endif /* USE_OPLOCKS */ -#endif /* FAST_SHARE_MODES */ +#define LOCKING_VERSION 3 /* these are useful macros for checking validity of handles */ #define VALID_FNUM(fnum) (((fnum) >= 0) && ((fnum) < MAX_OPEN_FILES)) @@ -575,7 +526,11 @@ struct connect_record #define IS_HIDDEN_PATH(cnum,path) (is_in_path((path),Connections[(cnum)].hide_list)) #define IS_VETO_PATH(cnum,path) (is_in_path((path),Connections[(cnum)].veto_list)) +#ifdef SMB_PASSWD #define SMBENCRYPT() (lp_encrypted_passwords()) +#else +#define SMBENCRYPT() (False) +#endif /* the basic packet size, assuming no words or bytes */ #define smb_size 39 @@ -971,99 +926,18 @@ enum case_handling {CASE_LOWER,CASE_UPPER}; #endif -/* Defines needed for multi-codepage support. */ -#define KANJI_CODEPAGE 932 - #ifdef KANJI -/* - * Default client code page - Japanese - */ -#define DEFAULT_CLIENT_CODE_PAGE KANJI_CODEPAGE +/* Default client code page - 932 - Japanese */ +#define DEFAULT_CLIENT_CODE_PAGE 932 #else /* KANJI */ -/* - * Default client code page - 850 - Western European - */ +/* Default client code page - 850 - Western European */ #define DEFAULT_CLIENT_CODE_PAGE 850 #endif /* KANJI */ -/* - * Size of buffer to use when moving files across filesystems. - */ +/* Size of buffer to use when moving files across filesystems. */ #define COPYBUF_SIZE (8*1024) -/* - * Integers used to override error codes. - */ +/* Integers used to override error codes. */ extern int unix_ERR_class; extern int unix_ERR_code; - -/* - * Map the Core and Extended Oplock requesst bits down - * to common bits (EXCLUSIVE_OPLOCK & BATCH_OPLOCK). - */ - -/* - * Core protocol. - */ -#define CORE_OPLOCK_REQUEST(inbuf) (((CVAL(inbuf,smb_flg)|(1<<5))>>5) | \ - ((CVAL(inbuf,smb_flg)|(1<<6))>>5)) - -/* - * Extended protocol. - */ -#define EXTENDED_OPLOCK_REQUEST(inbuf) (((SVAL(inbuf,smb_vwv2)|(1<<1))>>1) | \ - ((SVAL(inbuf,smb_vwv2)|(1<<2))>>1)) - -/* Lock types. */ -#define LOCKING_ANDX_SHARED_LOCK 0x1 -#define LOCKING_ANDX_OPLOCK_RELEASE 0x2 -#define LOCKING_ANDX_CHANGE_LOCKTYPE 0x4 -#define LOCKING_ANDX_CANCEL_LOCK 0x8 -#define LOCKING_ANDX_LARGE_FILES 0x10 - -/* Oplock levels */ -#define OPLOCKLEVEL_NONE 0 -#define OPLOCKLEVEL_II 1 - -/* - * Bits we test with. - */ -#define EXCLUSIVE_OPLOCK 1 -#define BATCH_OPLOCK 2 - -#define CORE_OPLOCK_GRANTED (1<<5) -#define EXTENDED_OPLOCK_GRANTED (1<<15) - -/* - * Loopback command offsets. - */ - -#define UDP_CMD_LEN_OFFSET 0 -#define UDP_CMD_PORT_OFFSET 4 -#define UDP_CMD_HEADER_LEN 6 - -#define UDP_MESSAGE_CMD_OFFSET 0 - -/* - * Oplock break command code to send over the udp socket. - * - * Form of this is : - * - * 0 2 6 10 14 18 22 - * +----+--------+--------+--------+-------+--------+ - * | cmd| pid | dev | inode | sec | usec | - * +----+--------+--------+--------+-------+--------+ - */ - -#define OPLOCK_BREAK_CMD 0x1 -#define OPLOCK_BREAK_PID_OFFSET 2 -#define OPLOCK_BREAK_DEV_OFFSET 6 -#define OPLOCK_BREAK_INODE_OFFSET 10 -#define OPLOCK_BREAK_SEC_OFFSET 14 -#define OPLOCK_BREAK_USEC_OFFSET 18 -#define OPLOCK_BREAK_MSG_LEN 22 - - -#define CMD_REPLY 0x8000 - /* _SMB_H */ diff --git a/source/include/version.h b/source/include/version.h index 33c9d240baf..7bea7836bc6 100644 --- a/source/include/version.h +++ b/source/include/version.h @@ -1 +1 @@ -#define VERSION "1.9.18alpha1" +#define VERSION "1.9.17p3" diff --git a/source/lib/access.c b/source/lib/access.c index c338517ed67..599cb5ca7e3 100644 --- a/source/lib/access.c +++ b/source/lib/access.c @@ -70,8 +70,8 @@ BOOL check_access(int snum) } else if (snum >= 0) - DEBUG(0,("%s Denied connection from %s (%s) to %s\n", - timestring(), client_name(),client_addr(), + DEBUG(0,("Denied connection from %s (%s) to %s\n", + client_name(),client_addr(), lp_servicename(snum))); } diff --git a/source/lib/charcnv.c b/source/lib/charcnv.c index a7dff4224be..6be455c47b2 100644 --- a/source/lib/charcnv.c +++ b/source/lib/charcnv.c @@ -107,18 +107,13 @@ char *unix2dos_format(char *str,BOOL overwrite) char *dp; if (!mapsinited) initmaps(); - - if(lp_client_code_page() == KANJI_CODEPAGE) - return (*_unix_to_dos)(str, overwrite); - else { - if (overwrite) { - for (p = str; *p; p++) *p = unix2dos[(unsigned char)*p]; - return str; - } else { - for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = unix2dos[(unsigned char)*p]; - *dp = 0; - return cvtbuf; - } + if (overwrite) { + for (p = str; *p; p++) *p = unix2dos[(unsigned char)*p]; + return str; + } else { + for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = unix2dos[(unsigned char)*p]; + *dp = 0; + return cvtbuf; } } @@ -131,18 +126,13 @@ char *dos2unix_format(char *str, BOOL overwrite) char *dp; if (!mapsinited) initmaps(); - - if(lp_client_code_page() == KANJI_CODEPAGE) - return (*_dos_to_unix)(str, overwrite); - else { - if (overwrite) { - for (p = str; *p; p++) *p = dos2unix[(unsigned char)*p]; - return str; - } else { - for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = dos2unix[(unsigned char)*p]; - *dp = 0; - return cvtbuf; - } + if (overwrite) { + for (p = str; *p; p++) *p = dos2unix[(unsigned char)*p]; + return str; + } else { + for (p = str, dp = cvtbuf; *p; p++,dp++) *dp = dos2unix[(unsigned char)*p]; + *dp = 0; + return cvtbuf; } } diff --git a/source/lib/charset.c b/source/lib/charset.c index 4869e09fecf..c4f67e75fb1 100644 --- a/source/lib/charset.c +++ b/source/lib/charset.c @@ -28,7 +28,6 @@ extern int DEBUGLEVEL; * Codepage definitions. */ -#if !defined(KANJI) /* lower->upper mapping for IBM Code Page 850 - MS-DOS Latin 1 */ unsigned char cp_850[][4] = { /* dec col/row oct hex description */ @@ -96,13 +95,74 @@ unsigned char cp_850[][4] = { {0x9C,0,0,0}, /* Pound */ {0,0,0,0} }; -#else /* KANJI */ + +/* lower->upper mapping for IBM Code Page 437 - MS-DOS Latin US */ +unsigned char cp_437[][4] = { +/* 135 08/07 207 87 c cedilla */ +/* 128 08/00 200 80 C cedilla */ {0x87,0x80,1,1}, +/* 129 08/01 201 81 u diaeresis */ +/* 154 09/10 232 9A U diaeresis */ {0x81,0x9A,1,1}, +/* 130 08/02 202 82 e acute */ +/* 144 09/00 220 90 E acute */ {0x82,0x90,1,1}, +/* 131 08/03 203 83 a circumflex */ {0x83,0x41,1,0}, +/* 132 08/04 204 84 a diaeresis */ +/* 142 08/14 216 8E A diaeresis */ {0x84,0x8E,1,1}, +/* 133 08/05 205 85 a grave */ {0x85,0x41,1,0}, +/* 134 08/06 206 86 a ring */ {0x86,0x8F,1,1}, +/* 136 08/08 210 88 e circumflex */ {0x88,0x45,1,0}, +/* 137 08/09 211 89 e diaeresis */ {0x89,0x45,1,0}, +/* 138 08/10 212 8A e grave */ {0x8A,0x45,1,0}, +/* 139 08/11 213 8B i diaeresis */ {0x8B,0x49,1,0}, +/* 140 08/12 214 8C i circumflex */ {0x8C,0x49,1,0}, +/* 141 08/13 215 8D i grave */ {0x8D,0x49,1,0}, +/* 145 09/01 221 91 ae diphthong */ +/* 146 09/02 222 92 AE diphthong */ {0x91,0x92,1,1}, +/* 147 09/03 223 93 o circumflex */ {0x93,0x4F,1,0}, +/* 148 09/04 224 94 o diaeresis */ +/* 153 09/09 231 99 O diaeresis */ {0x94,0x99,1,1}, +/* 149 09/05 225 95 o grave */ {0x95,0x4F,1,0}, +/* 150 09/06 226 96 u circumflex */ {0x96,0x55,1,0}, +/* 151 09/07 227 97 u grave */ {0x97,0x55,1,0}, +/* 152 ??/?? 201 98 u diaeresis */ + {0x9B,0,0,0}, /* Cent */ + {0x9C,0,0,0}, /* Pound */ + {0x9D,0,0,0}, /* Yen */ +/* 160 10/00 240 A0 a acute */ {0xA0,0x41,1,0}, +/* 161 10/01 241 A1 i acute */ {0xA1,0x49,1,0}, +/* 162 10/02 242 A2 o acute */ {0xA2,0x4F,1,0}, +/* 163 10/03 243 A3 u acute */ {0xA3,0x55,1,0}, +/* 164 10/04 244 A4 n tilde */ +/* 165 10/05 245 A5 N tilde */ {0xA4,0xA5,1,1}, +/* Punctuation... */ + {0xA8,0,0,0}, + {0xAD,0,0,0}, + {0xAE,0,0,0}, + {0xAF,0,0,0}, +/* Greek character set */ + {0xE0,0,0,0}, + {0xE1,0,0,0}, + {0xE2,0,0,0}, + {0xE3,0,0,0}, + {0xE4,0,0,0}, + {0xE5,0,0,0}, + {0xE6,0,0,0}, + {0xE7,0,0,0}, + {0xE8,0,0,0}, + {0xE9,0,0,0}, + {0xEA,0,0,0}, + {0xEB,0,0,0}, + {0xEC,0,0,0}, + {0xED,0,0,0}, + {0xEE,0,0,0}, + {0xEF,0,0,0}, + {0,0,0,0} +}; + /* lower->upper mapping for IBM Code Page 932 - MS-DOS Japanese SJIS */ unsigned char cp_932[][4] = { {0,0,0,0} }; -#endif /* KANJI */ - + char xx_dos_char_map[256]; char xx_upper_char_map[256]; char xx_lower_char_map[256]; @@ -134,9 +194,9 @@ static void add_dos_char(int lower, BOOL map_lower_to_upper, if (upper) dos_char_map[upper] = 1; if (lower && upper) { if(map_upper_to_lower) - lower_char_map[upper] = (char)lower; + lower_char_map[upper] = (char)lower; if(map_lower_to_upper) - upper_char_map[lower] = (char)upper; + upper_char_map[lower] = (char)upper; } } @@ -171,152 +231,12 @@ void charset_initialise() } /**************************************************************************** -load the client codepage. -****************************************************************************/ - -typedef unsigned char (*codepage_p)[4]; - -static codepage_p load_client_codepage( int client_codepage ) -{ - pstring codepage_file_name; - unsigned char buf[8]; - FILE *fp = NULL; - unsigned int size; - codepage_p cp_p = NULL; - struct stat st; - - DEBUG(5, ("load_client_codepage: loading codepage %d.\n", client_codepage)); - - if(strlen(CODEPAGEDIR) + 14 > sizeof(codepage_file_name)) - { - DEBUG(0,("load_client_codepage: filename too long to load\n")); - return NULL; - } - - strcpy(codepage_file_name, CODEPAGEDIR); - strcat(codepage_file_name, "/"); - strcat(codepage_file_name, "codepage."); - sprintf( &codepage_file_name[strlen(codepage_file_name)], "%03d", - client_codepage); - - if(!file_exist(codepage_file_name,&st)) - { - DEBUG(0,("load_client_codepage: filename %s does not exist.\n", - codepage_file_name)); - return NULL; - } - - /* Check if it is at least big enough to hold the required - data. Should be 2 byte version, 2 byte codepage, 4 byte length, - plus zero or more bytes of data. Note that the data cannot be more - than 512 bytes - giving a max size of 520. - */ - size = (unsigned int)st.st_size; - - if( size < CODEPAGE_HEADER_SIZE || size > (CODEPAGE_HEADER_SIZE + 256)) - { - DEBUG(0,("load_client_codepage: file %s is an incorrect size for a \ -code page file.\n", codepage_file_name)); - return NULL; - } - - /* Read the first 8 bytes of the codepage file - check - the version number and code page number. All the data - is held in little endian format. - */ - - if((fp = fopen( codepage_file_name, "r")) == NULL) - { - DEBUG(0,("load_client_codepage: cannot open file %s. Error was %s\n", - codepage_file_name, strerror(errno))); - return NULL; - } - - if(fread( buf, 1, CODEPAGE_HEADER_SIZE, fp)!=CODEPAGE_HEADER_SIZE) - { - DEBUG(0,("load_client_codepage: cannot read header from file %s. Error was %s\n", - codepage_file_name, strerror(errno))); - goto clean_and_exit; - } - - /* Check the version value */ - if(SVAL(buf,CODEPAGE_VERSION_OFFSET) != CODEPAGE_FILE_VERSION_ID) - { - DEBUG(0,("load_client_codepage: filename %s has incorrect version id. \ -Needed %hu, got %hu.\n", - codepage_file_name, (uint16)CODEPAGE_FILE_VERSION_ID, - SVAL(buf,CODEPAGE_VERSION_OFFSET))); - goto clean_and_exit; - } - - /* Check the codepage matches */ - if(SVAL(buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET) != (uint16)client_codepage) - { - DEBUG(0,("load_client_codepage: filename %s has incorrect codepage. \ -Needed %hu, got %hu.\n", - codepage_file_name, (uint16)client_codepage, - SVAL(buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET))); - goto clean_and_exit; - } - - /* Check the length is correct. */ - if(IVAL(buf,CODEPAGE_LENGTH_OFFSET) != - (unsigned int)(size - CODEPAGE_HEADER_SIZE)) - { - DEBUG(0,("load_client_codepage: filename %s has incorrect size headers. \ -Needed %u, got %u.\n", codepage_file_name, size - CODEPAGE_HEADER_SIZE, - IVAL(buf,CODEPAGE_LENGTH_OFFSET))); - goto clean_and_exit; - } - - size -= CODEPAGE_HEADER_SIZE; /* Remove header */ - - /* Make sure the size is a multiple of 4. */ - if((size % 4 ) != 0) - { - DEBUG(0,("load_client_codepage: filename %s has a codepage size not a \ -multiple of 4.\n", codepage_file_name)); - goto clean_and_exit; - } - - /* Allocate space for the code page file and read it all in. */ - if((cp_p = (codepage_p)malloc( size + 4 )) == NULL) - { - DEBUG(0,("load_client_codepage: malloc fail.\n")); - goto clean_and_exit; - } - - if(fread( (char *)cp_p, 1, size, fp)!=size) - { - DEBUG(0,("load_client_codepage: read fail on file %s. Error was %s.\n", - codepage_file_name, strerror(errno))); - goto clean_and_exit; - } - - /* Ensure array is correctly terminated. */ - memset(((char *)cp_p) + size, '\0', 4); - - fclose(fp); - return cp_p; - -clean_and_exit: - - /* pseudo destructor :-) */ - - if(fp != NULL) - fclose(fp); - if(cp_p) - free((char *)cp_p); - return NULL; -} - -/**************************************************************************** initialise the client codepage. ****************************************************************************/ void codepage_initialise(int client_codepage) { int i; - codepage_p cp = NULL; + unsigned char (*cp)[4] = NULL; static BOOL done = False; if(done == True) @@ -332,21 +252,30 @@ void codepage_initialise(int client_codepage) /* * Known client codepages - these can be added to. */ - cp = load_client_codepage( client_codepage ); - - if(cp == NULL) + switch(client_codepage) { + case 850: + cp = cp_850; + break; + case 437: + cp = cp_437; + break; + case 932: + cp = cp_932; + break; + default: #ifdef KANJI - DEBUG(6,("codepage_initialise: loading dynamic codepage file %s/codepage.%d \ -for code page %d failed. Using default client codepage 932\n", - CODEPAGEDIR, client_codepage, client_codepage)); - cp = cp_932; + /* Use default codepage - currently 932 */ + DEBUG(6,("codepage_initialise: Using default client codepage %d\n", + 932)); + cp = cp_932; #else /* KANJI */ - DEBUG(6,("codepage_initialise: loading dynamic codepage file %s/codepage.%d \ -for code page %d failed. Using default client codepage 850\n", - CODEPAGEDIR, client_codepage, client_codepage)); - cp = cp_850; + /* Use default codepage - currently 850 */ + DEBUG(6,("codepage_initialise: Using default client codepage %d\n", + 850)); + cp = cp_850; #endif /* KANJI */ + break; } if(cp) diff --git a/source/lib/getsmbpass.c b/source/lib/getsmbpass.c index e8cb683d0b1..9008d40f910 100644 --- a/source/lib/getsmbpass.c +++ b/source/lib/getsmbpass.c @@ -45,7 +45,7 @@ static struct termio t; return ioctl(fd, TCGETA, t); } - int tcsetattr(int fd, int flags, struct termio *t) + int tcsetattr(int fd, int flags, const struct termio *t) { if(flags & TCSAFLUSH) ioctl(fd, TCFLSH, TCIOFLUSH); @@ -76,7 +76,7 @@ static struct sgttyb t; return ioctl(fd, TIOCGETP, (char *)t); } - int tcsetattr(int fd, int flags, struct sgttyb *t) + int tcsetattr(int fd, int flags, const struct sgttyb *t) { return ioctl(fd, TIOCSETP, (char *)t); } diff --git a/source/lib/interface.c b/source/lib/interface.c index 940af1eccf4..147425d0fc1 100644 --- a/source/lib/interface.c +++ b/source/lib/interface.c @@ -337,9 +337,9 @@ static void interpret_interfaces(char *s, struct interface **interfaces, iface->next = NULL; (*interfaces) = last_iface = iface; - DEBUG(1,("Added interface ip=%s ",inet_ntoa(iface->ip))); - DEBUG(1,("bcast=%s ",inet_ntoa(iface->bcast))); - DEBUG(1,("nmask=%s\n",inet_ntoa(iface->nmask))); + DEBUG(2,("Added interface ip=%s ",inet_ntoa(iface->ip))); + DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast))); + DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask))); } diff --git a/source/lib/kanji.c b/source/lib/kanji.c index 5d7de87248d..479763fd406 100644 --- a/source/lib/kanji.c +++ b/source/lib/kanji.c @@ -23,6 +23,7 @@ and add all jis codes sequence type at 1995.8.16 Notes: Hexadecimal code by <ohki@gssm.otuka.tsukuba.ac.jp> */ +#ifdef KANJI #define _KANJI_C_ #include "includes.h" @@ -42,7 +43,8 @@ char hex_tag = HEXTAG; search token from S1 separated any char of S2 S1 contain SHIFT JIS chars. ********************************************************************/ -char *sj_strtok(char *s1, char *s2) +char * +sj_strtok (char *s1, const char *s2) { static char *s = NULL; char *q; @@ -81,9 +83,10 @@ char *sj_strtok(char *s1, char *s2) search string S2 from S1 S1 contain SHIFT JIS chars. ********************************************************************/ -char *sj_strstr(char *s1, char *s2) +char * +sj_strstr (const char *s1, const char *s2) { - int len = strlen ((char *) s2); + register int len = strlen ((char *) s2); if (!*s2) return (char *) s1; for (;*s1;) { @@ -104,7 +107,8 @@ char *sj_strstr(char *s1, char *s2) Search char C from beginning of S. S contain SHIFT JIS chars. ********************************************************************/ -char *sj_strchr (char *s, int c) +char * +sj_strchr (const char *s, int c) { for (; *s; ) { if (*s == c) @@ -122,9 +126,10 @@ char *sj_strchr (char *s, int c) Search char C end of S. S contain SHIFT JIS chars. ********************************************************************/ -char *sj_strrchr(char *s, int c) +char * +sj_strrchr (const char *s, int c) { - char *q; + register char *q; for (q = 0; *s; ) { if (*s == c) { @@ -148,7 +153,8 @@ static char cvtbuf[1024]; /******************************************************************* EUC <-> SJIS ********************************************************************/ -static int euc2sjis (int hi, int lo) +static int +euc2sjis (register int hi, register int lo) { if (hi & 1) return ((hi / 2 + (hi < 0xdf ? 0x31 : 0x71)) << 8) | @@ -157,7 +163,8 @@ static int euc2sjis (int hi, int lo) return ((hi / 2 + (hi < 0xdf ? 0x30 : 0x70)) << 8) | (lo - 2); } -static int sjis2euc (int hi, int lo) +static int +sjis2euc (register int hi, register int lo) { if (lo >= 0x9f) return ((hi * 2 - (hi >= 0xe0 ? 0xe0 : 0x60)) << 8) | (lo + 2); @@ -170,9 +177,10 @@ static int sjis2euc (int hi, int lo) Convert FROM contain SHIFT JIS codes to EUC codes return converted buffer ********************************************************************/ -static char *sj_to_euc(char *from, BOOL overwrite) +static char * +sj_to_euc (const char *from, BOOL overwrite) { - char *out; + register char *out; char *save; save = (char *) from; @@ -202,9 +210,10 @@ static char *sj_to_euc(char *from, BOOL overwrite) Convert FROM contain EUC codes to SHIFT JIS codes return converted buffer ********************************************************************/ -static char *euc_to_sj(char *from, BOOL overwrite) +static char * +euc_to_sj (const char *from, BOOL overwrite) { - char *out; + register char *out; char *save; save = (char *) from; @@ -233,7 +242,8 @@ static char *euc_to_sj(char *from, BOOL overwrite) /******************************************************************* JIS7,JIS8,JUNET <-> SJIS ********************************************************************/ -static int sjis2jis(int hi, int lo) +static int +sjis2jis (register int hi, register int lo) { if (lo >= 0x9f) return ((hi * 2 - (hi >= 0xe0 ? 0x160 : 0xe0)) << 8) | (lo - 0x7e); @@ -242,7 +252,8 @@ static int sjis2jis(int hi, int lo) (lo - (lo >= 0x7f ? 0x20 : 0x1f)); } -static int jis2sjis(int hi, int lo) +static int +jis2sjis (register int hi, register int lo) { if (hi & 1) return ((hi / 2 + (hi < 0x5f ? 0x71 : 0xb1)) << 8) | @@ -255,10 +266,11 @@ static int jis2sjis(int hi, int lo) Convert FROM contain JIS codes to SHIFT JIS codes return converted buffer ********************************************************************/ -static char *jis8_to_sj(char *from, BOOL overwrite) +static char * +jis8_to_sj (const char *from, BOOL overwrite) { - char *out; - int shifted; + register char *out; + register int shifted; char *save; shifted = _KJ_ROMAN; @@ -305,10 +317,11 @@ static char *jis8_to_sj(char *from, BOOL overwrite) Convert FROM contain SHIFT JIS codes to JIS codes return converted buffer ********************************************************************/ -static char *sj_to_jis8(char *from, BOOL overwrite) +static char * +sj_to_jis8 (const char *from, BOOL overwrite) { - char *out; - int shifted; + register char *out; + register int shifted; char *save; shifted = _KJ_ROMAN; @@ -361,10 +374,11 @@ static char *sj_to_jis8(char *from, BOOL overwrite) 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 (const char *from, BOOL overwrite) { - char *out; - int shifted; + register char *out; + register int shifted; char *save; shifted = _KJ_ROMAN; @@ -420,10 +434,11 @@ static char *jis7_to_sj(char *from, BOOL overwrite) 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 (const char *from, BOOL overwrite) { - char *out; - int shifted; + register char *out; + register int shifted; char *save; shifted = _KJ_ROMAN; @@ -496,10 +511,11 @@ static char *sj_to_jis7(char *from, BOOL overwrite) Convert FROM contain 7 bits JIS(junet) codes to SHIFT JIS codes return converted buffer ********************************************************************/ -static char *junet_to_sj(char *from, BOOL overwrite) +static char * +junet_to_sj (const char *from, BOOL overwrite) { - char *out; - int shifted; + register char *out; + register int shifted; char *save; shifted = _KJ_ROMAN; @@ -552,10 +568,11 @@ static char *junet_to_sj(char *from, BOOL overwrite) 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 (const char *from, BOOL overwrite) { - char *out; - int shifted; + register char *out; + register int shifted; char *save; shifted = _KJ_ROMAN; @@ -621,7 +638,8 @@ static char *sj_to_junet(char *from, BOOL overwrite) HEX <-> SJIS ********************************************************************/ /* ":xx" -> a byte */ -static char *hex_to_sj(char *from, BOOL overwrite) +static char * +hex_to_sj (const char *from, BOOL overwrite) { char *sp, *dp; @@ -646,7 +664,8 @@ static char *hex_to_sj(char *from, BOOL overwrite) /******************************************************************* kanji/kana -> ":xx" ********************************************************************/ -static char *sj_to_hex(char *from, BOOL overwrite) +static char * +sj_to_hex (const char *from, BOOL overwrite) { unsigned char *sp, *dp; @@ -682,7 +701,8 @@ static char *sj_to_hex(char *from, BOOL overwrite) /******************************************************************* kanji/kana -> ":xx" ********************************************************************/ -static char *sj_to_cap(char *from, BOOL overwrite) +static char * +sj_to_cap (const char *from, BOOL overwrite) { unsigned char *sp, *dp; @@ -710,7 +730,8 @@ static char *sj_to_cap(char *from, BOOL overwrite) /******************************************************************* sj to sj ********************************************************************/ -static char *sj_to_sj(char *from, BOOL overwrite) +static char * +sj_to_sj (const char *from, BOOL overwrite) { if (!overwrite) { strcpy (cvtbuf, (char *) from); @@ -725,10 +746,11 @@ static char *sj_to_sj(char *from, BOOL overwrite) _dos_to_unix _unix_to_dos ************************************************************************/ -char *(*_dos_to_unix)(char *str, BOOL overwrite) = sj_to_sj; -char *(*_unix_to_dos)(char *str, BOOL overwrite) = sj_to_sj; +char* (*_dos_to_unix) (const char *str, BOOL overwrite) = sj_to_sj; +char* (*_unix_to_dos) (const char *str, BOOL overwrite) = sj_to_sj; -static int setup_string_function(int codes) +static int +setup_string_function (int codes) { switch (codes) { default: @@ -866,3 +888,7 @@ int interpret_coding_system(char *str, int def) } return setup_string_function (codes); } +#else + int kanji_dummy_procedure(void) +{return 0;} +#endif /* KANJI */ diff --git a/source/lib/md4.c b/source/lib/md4.c index 1c9c2e6ecd5..bdff075c7e7 100644 --- a/source/lib/md4.c +++ b/source/lib/md4.c @@ -1,171 +1,299 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - a implementation of MD4 designed for use in the SMB authentication protocol - Copyright (C) Andrew Tridgell 1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#ifdef SMB_PASSWD +/* + This code is from rfc1186. */ + /* + ** ******************************************************************** + ** md4.c -- Implementation of MD4 Message Digest Algorithm ** + ** Updated: 2/16/90 by Ronald L. Rivest ** + ** (C) 1990 RSA Data Security, Inc. ** + ** ******************************************************************** + */ -/* NOTE: This code makes no attempt to be fast! + /* + ** To use MD4: + ** -- Include md4.h in your program + ** -- Declare an MDstruct MD to hold the state of the digest + ** computation. + ** -- Initialize MD using MDbegin(&MD) + ** -- For each full block (64 bytes) X you wish to process, call + ** MDupdate(&MD,X,512) + ** (512 is the number of bits in a full block.) + ** -- For the last block (less than 64 bytes) you wish to process, + ** MDupdate(&MD,X,n) + ** where n is the number of bits in the partial block. A partial + ** block terminates the computation, so every MD computation + ** should terminate by processing a partial block, even if it + ** has n = 0. + ** -- The message digest is available in MD.buffer[0] ... + ** MD.buffer[3]. (Least-significant byte of each word + ** should be output first.) + ** -- You can print out the digest using MDprint(&MD) + */ - It assumes that a int is at least 32 bits long -*/ + /* Implementation notes: + ** This implementation assumes that ints are 32-bit quantities. + ** If the machine stores the least-significant byte of an int in the + ** least-addressed byte (e.g., VAX and 8086), then LOWBYTEFIRST + ** should be set to TRUE. Otherwise (e.g., SUNS), LOWBYTEFIRST + ** should be set to FALSE. Note that on machines with LOWBYTEFIRST + ** FALSE the routine MDupdate modifies has a side-effect on its input + ** array (the order of bytes in each word are reversed). If this is + ** undesired a call to MDreverse(X) can reverse the bytes of X back + ** into order after each call to MDupdate. + */ -typedef unsigned int uint32; - -static uint32 A, B, C, D; - -static uint32 F(uint32 X, uint32 Y, uint32 Z) -{ - return (X&Y) | ((~X)&Z); -} - -static uint32 G(uint32 X, uint32 Y, uint32 Z) -{ - return (X&Y) | (X&Z) | (Y&Z); -} - -static uint32 H(uint32 X, uint32 Y, uint32 Z) -{ - return X^Y^Z; -} - -static uint32 lshift(uint32 x, int s) -{ - x &= 0xFFFFFFFF; - return ((x<<s)&0xFFFFFFFF) | (x>>(32-s)); -} - -#define ROUND1(a,b,c,d,k,s) a = lshift(a + F(b,c,d) + X[k], s) -#define ROUND2(a,b,c,d,k,s) a = lshift(a + G(b,c,d) + X[k] + (uint32)0x5A827999,s) -#define ROUND3(a,b,c,d,k,s) a = lshift(a + H(b,c,d) + X[k] + (uint32)0x6ED9EBA1,s) - -/* this applies md4 to 64 byte chunks */ -static void mdfour64(uint32 *M) -{ - int j; - uint32 AA, BB, CC, DD; - uint32 X[16]; - - for (j=0;j<16;j++) - X[j] = M[j]; - - AA = A; BB = B; CC = C; DD = D; - - ROUND1(A,B,C,D, 0, 3); ROUND1(D,A,B,C, 1, 7); - ROUND1(C,D,A,B, 2, 11); ROUND1(B,C,D,A, 3, 19); - ROUND1(A,B,C,D, 4, 3); ROUND1(D,A,B,C, 5, 7); - ROUND1(C,D,A,B, 6, 11); ROUND1(B,C,D,A, 7, 19); - ROUND1(A,B,C,D, 8, 3); ROUND1(D,A,B,C, 9, 7); - ROUND1(C,D,A,B, 10, 11); ROUND1(B,C,D,A, 11, 19); - ROUND1(A,B,C,D, 12, 3); ROUND1(D,A,B,C, 13, 7); - ROUND1(C,D,A,B, 14, 11); ROUND1(B,C,D,A, 15, 19); - - ROUND2(A,B,C,D, 0, 3); ROUND2(D,A,B,C, 4, 5); - ROUND2(C,D,A,B, 8, 9); ROUND2(B,C,D,A, 12, 13); - ROUND2(A,B,C,D, 1, 3); ROUND2(D,A,B,C, 5, 5); - ROUND2(C,D,A,B, 9, 9); ROUND2(B,C,D,A, 13, 13); - ROUND2(A,B,C,D, 2, 3); ROUND2(D,A,B,C, 6, 5); - ROUND2(C,D,A,B, 10, 9); ROUND2(B,C,D,A, 14, 13); - ROUND2(A,B,C,D, 3, 3); ROUND2(D,A,B,C, 7, 5); - ROUND2(C,D,A,B, 11, 9); ROUND2(B,C,D,A, 15, 13); - - ROUND3(A,B,C,D, 0, 3); ROUND3(D,A,B,C, 8, 9); - ROUND3(C,D,A,B, 4, 11); ROUND3(B,C,D,A, 12, 15); - ROUND3(A,B,C,D, 2, 3); ROUND3(D,A,B,C, 10, 9); - ROUND3(C,D,A,B, 6, 11); ROUND3(B,C,D,A, 14, 15); - ROUND3(A,B,C,D, 1, 3); ROUND3(D,A,B,C, 9, 9); - ROUND3(C,D,A,B, 5, 11); ROUND3(B,C,D,A, 13, 15); - ROUND3(A,B,C,D, 3, 3); ROUND3(D,A,B,C, 11, 9); - ROUND3(C,D,A,B, 7, 11); ROUND3(B,C,D,A, 15, 15); - - A += AA; B += BB; C += CC; D += DD; - - A &= 0xFFFFFFFF; B &= 0xFFFFFFFF; - C &= 0xFFFFFFFF; D &= 0xFFFFFFFF; - - for (j=0;j<16;j++) - X[j] = 0; -} - -static void copy64(uint32 *M, unsigned char *in) -{ - int i; - - for (i=0;i<16;i++) - M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) | - (in[i*4+1]<<8) | (in[i*4+0]<<0); -} - -static void copy4(unsigned char *out,uint32 x) -{ - out[0] = x&0xFF; - out[1] = (x>>8)&0xFF; - out[2] = (x>>16)&0xFF; - out[3] = (x>>24)&0xFF; -} - -/* produce a md4 message digest from data of length n bytes */ -void mdfour(unsigned char *out, unsigned char *in, int n) -{ - unsigned char buf[128]; - uint32 M[16]; - uint32 b = n * 8; - int i; - - A = 0x67452301; - B = 0xefcdab89; - C = 0x98badcfe; - D = 0x10325476; - - while (n > 64) { - copy64(M, in); - mdfour64(M); - in += 64; - n -= 64; - } +#define TRUE 1 +#define FALSE 0 - for (i=0;i<128;i++) - buf[i] = 0; - memcpy(buf, in, n); - buf[n] = 0x80; - - if (n <= 55) { - copy4(buf+56, b); - copy64(M, buf); - mdfour64(M); - } else { - copy4(buf+120, b); - copy64(M, buf); - mdfour64(M); - copy64(M, buf+64); - mdfour64(M); - } + /* Compile-time includes + */ + +#include <stdio.h> +#include "md4.h" + +#define uchar unsigned char +#define int16 unsigned short +#define uint32 unsigned int + +#include "byteorder.h" + + /* Compile-time declarations of MD4 "magic constants". + */ +#define I0 0x67452301 /* Initial values for MD buffer */ +#define I1 0xefcdab89 +#define I2 0x98badcfe +#define I3 0x10325476 +#define C2 013240474631 /* round 2 constant = sqrt(2) in octal */ +#define C3 015666365641 /* round 3 constant = sqrt(3) in octal */ + /* C2 and C3 are from Knuth, The Art of Programming, Volume 2 + ** (Seminumerical Algorithms), Second Edition (1981), Addison-Wesley. + ** Table 2, page 660. + */ - for (i=0;i<128;i++) - buf[i] = 0; - copy64(M, buf); +#define fs1 3 /* round 1 shift amounts */ +#define fs2 7 +#define fs3 11 +#define fs4 19 +#define gs1 3 /* round 2 shift amounts */ +#define gs2 5 +#define gs3 9 +#define gs4 13 +#define hs1 3 /* round 3 shift amounts */ +#define hs2 9 +#define hs3 11 +#define hs4 15 - copy4(out, A); - copy4(out+4, B); - copy4(out+8, C); - copy4(out+12, D); + /* Compile-time macro declarations for MD4. + ** Note: The "rot" operator uses the variable "tmp". + ** It assumes tmp is declared as unsigned int, so that the >> + ** operator will shift in zeros rather than extending the sign bit. + */ +#define f(X,Y,Z) ((X&Y) | ((~X)&Z)) +#define g(X,Y,Z) ((X&Y) | (X&Z) | (Y&Z)) +#define h(X,Y,Z) (X^Y^Z) +#define rot(X,S) (tmp=X,(tmp<<S) | (tmp>>(32-S))) +#define ff(A,B,C,D,i,s) A = rot((A + f(B,C,D) + X[i]),s) +#define gg(A,B,C,D,i,s) A = rot((A + g(B,C,D) + X[i] + C2),s) +#define hh(A,B,C,D,i,s) A = rot((A + h(B,C,D) + X[i] + C3),s) + + /* MDprint(MDp) + ** Print message digest buffer MDp as 32 hexadecimal digits. + ** Order is from low-order byte of buffer[0] to high-order byte of + ** buffer[3]. + ** Each byte is printed with high-order hexadecimal digit first. + ** This is a user-callable routine. + */ + void + MDprint(MDp) + MDptr MDp; + { int i,j; + for (i=0;i<4;i++) + for (j=0;j<32;j=j+8) + printf("%02x",(MDp->buffer[i]>>j) & 0xFF); + } + + /* MDbegin(MDp) + ** Initialize message digest buffer MDp. + ** This is a user-callable routine. + */ + void + MDbegin(MDp) + MDptr MDp; + { int i; + MDp->buffer[0] = I0; + MDp->buffer[1] = I1; + MDp->buffer[2] = I2; + MDp->buffer[3] = I3; + for (i=0;i<8;i++) MDp->count[i] = 0; + MDp->done = 0; + } + + /* MDreverse(X) + ** Reverse the byte-ordering of every int in X. + ** Assumes X is an array of 16 ints. + ** The macro revx reverses the byte-ordering of the next word of X. + */ + void MDreverse(X) + unsigned int *X; + { register unsigned int t; + register unsigned int i; + + for(i = 0; i < 16; i++) { + t = X[i]; + SIVAL(X,i*4,t); + } + } - A = B = C = D = 0; -} + /* MDblock(MDp,X) + ** Update message digest buffer MDp->buffer using 16-word data block X. + ** Assumes all 16 words of X are full of data. + ** Does not update MDp->count. + ** This routine is not user-callable. + */ + static void + MDblock(MDp,X) + MDptr MDp; + unsigned int *X; + { + register unsigned int tmp, A, B, C, D; + MDreverse(X); + A = MDp->buffer[0]; + B = MDp->buffer[1]; + C = MDp->buffer[2]; + D = MDp->buffer[3]; + /* Update the message digest buffer */ + ff(A , B , C , D , 0 , fs1); /* Round 1 */ + ff(D , A , B , C , 1 , fs2); + ff(C , D , A , B , 2 , fs3); + ff(B , C , D , A , 3 , fs4); + ff(A , B , C , D , 4 , fs1); + ff(D , A , B , C , 5 , fs2); + ff(C , D , A , B , 6 , fs3); + ff(B , C , D , A , 7 , fs4); + ff(A , B , C , D , 8 , fs1); + ff(D , A , B , C , 9 , fs2); + ff(C , D , A , B , 10 , fs3); + ff(B , C , D , A , 11 , fs4); + ff(A , B , C , D , 12 , fs1); + ff(D , A , B , C , 13 , fs2); + ff(C , D , A , B , 14 , fs3); + ff(B , C , D , A , 15 , fs4); + gg(A , B , C , D , 0 , gs1); /* Round 2 */ + gg(D , A , B , C , 4 , gs2); + gg(C , D , A , B , 8 , gs3); + gg(B , C , D , A , 12 , gs4); + gg(A , B , C , D , 1 , gs1); + gg(D , A , B , C , 5 , gs2); + gg(C , D , A , B , 9 , gs3); + gg(B , C , D , A , 13 , gs4); + gg(A , B , C , D , 2 , gs1); + gg(D , A , B , C , 6 , gs2); + gg(C , D , A , B , 10 , gs3); + gg(B , C , D , A , 14 , gs4); + gg(A , B , C , D , 3 , gs1); + gg(D , A , B , C , 7 , gs2); + gg(C , D , A , B , 11 , gs3); + gg(B , C , D , A , 15 , gs4); + hh(A , B , C , D , 0 , hs1); /* Round 3 */ + hh(D , A , B , C , 8 , hs2); + hh(C , D , A , B , 4 , hs3); + hh(B , C , D , A , 12 , hs4); + hh(A , B , C , D , 2 , hs1); + hh(D , A , B , C , 10 , hs2); + hh(C , D , A , B , 6 , hs3); + hh(B , C , D , A , 14 , hs4); + hh(A , B , C , D , 1 , hs1); + hh(D , A , B , C , 9 , hs2); + hh(C , D , A , B , 5 , hs3); + hh(B , C , D , A , 13 , hs4); + hh(A , B , C , D , 3 , hs1); + hh(D , A , B , C , 11 , hs2); + hh(C , D , A , B , 7 , hs3); + hh(B , C , D , A , 15 , hs4); + MDp->buffer[0] += A; + MDp->buffer[1] += B; + MDp->buffer[2] += C; + MDp->buffer[3] += D; + } + /* MDupdate(MDp,X,count) + ** Input: MDp -- an MDptr + ** X -- a pointer to an array of unsigned characters. + ** count -- the number of bits of X to use. + ** (if not a multiple of 8, uses high bits of last byte.) + ** Update MDp using the number of bits of X given by count. + ** This is the basic input routine for an MD4 user. + ** The routine completes the MD computation when count < 512, so + ** every MD computation should end with one call to MDupdate with a + ** count less than 512. A call with count 0 will be ignored if the + ** MD has already been terminated (done != 0), so an extra call with + ** count 0 can be given as a "courtesy close" to force termination + ** if desired. + */ + void + MDupdate(MDp,X,count) + MDptr MDp; + unsigned char *X; + unsigned int count; + { unsigned int i, tmp, bit, byte, mask; + unsigned char XX[64]; + unsigned char *p; + /* return with no error if this is a courtesy close with count + ** zero and MDp->done is true. + */ + if (count == 0 && MDp->done) return; + /* check to see if MD is already done and report error */ + if (MDp->done) + { printf("\nError: MDupdate MD already done."); return; } + /* Add count to MDp->count */ + tmp = count; + p = MDp->count; + while (tmp) + { tmp += *p; + *p++ = tmp; + tmp = tmp >> 8; + } + /* Process data */ + if (count == 512) + { /* Full block of data to handle */ + MDblock(MDp,(unsigned int *)X); + } + else if (count > 512) /* Check for count too large */ + { printf("\nError: MDupdate called with illegal count value %d." + ,count); + return; + } + else /* partial block -- must be last block so finish up */ + { /* Find out how many bytes and residual bits there are */ + byte = count >> 3; + bit = count & 7; + /* Copy X into XX since we need to modify it */ + for (i=0;i<=byte;i++) XX[i] = X[i]; + for (i=byte+1;i<64;i++) XX[i] = 0; + /* Add padding '1' bit and low-order zeros in last byte */ + mask = 1 << (7 - bit); + XX[byte] = (XX[byte] | mask) & ~( mask - 1); + /* If room for bit count, finish up with this block */ + if (byte <= 55) + { for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; + MDblock(MDp,(unsigned int *)XX); + } + else /* need to do two blocks to finish up */ + { MDblock(MDp,(unsigned int *)XX); + for (i=0;i<56;i++) XX[i] = 0; + for (i=0;i<8;i++) XX[56+i] = MDp->count[i]; + MDblock(MDp,(unsigned int *)XX); + } + /* Set flag saying we're done with MD computation */ + MDp->done = 1; + } + } + /* + ** End of md4.c + */ +#else + void md4_dummy() {;} +#endif diff --git a/source/lib/system.c b/source/lib/system.c index fe8e8004d04..b149ccb4b98 100644 --- a/source/lib/system.c +++ b/source/lib/system.c @@ -194,15 +194,25 @@ now for utime() ********************************************************************/ int sys_utime(char *fname,struct utimbuf *times) { - return(utime(dos_to_unix(fname,False),times)); + /* if the modtime is 0 or -1 then ignore the call and + return success */ + if (times->modtime == (time_t)0 || times->modtime == (time_t)-1) + return 0; + + /* if the access time is 0 or -1 then set it to the modtime */ + if (times->actime == (time_t)0 || times->actime == (time_t)-1) + times->actime = times->modtime; + + return(utime(dos_to_unix(fname,False),times)); } + /********************************************************* for rename across filesystems Patch from Warren Birnbaum <warrenb@hpcvscdp.cv.hp.com> **********************************************************/ - -static int copy_reg(char *source, const char *dest) +static int +copy_reg (const char *source, const char *dest) { struct stat source_stats; int ifd; diff --git a/source/lib/username.c b/source/lib/username.c index a9f64259916..46b8f4cb332 100644 --- a/source/lib/username.c +++ b/source/lib/username.c @@ -22,9 +22,6 @@ #include "includes.h" extern int DEBUGLEVEL; -/* internal functions - modified versions of the ones in password.c */ -static struct passwd *uname_string_combinations(char *s, struct passwd * (*fn) (), int N); -static struct passwd *uname_string_combinations2(char *s, int offset, struct passwd * (*fn) (), int N); /**************************************************************************** get a users home directory. tries as-is then lower case @@ -144,8 +141,6 @@ Note that this changes user! struct passwd *Get_Pwnam(char *user,BOOL allow_change) { fstring user2; - int last_char; - int usernamelevel = lp_usernamelevel(); struct passwd *ret; @@ -177,19 +172,6 @@ struct passwd *Get_Pwnam(char *user,BOOL allow_change) ret = _Get_Pwnam(user); if (ret) return(ret); - /* try with last letter capitalised */ - strlower(user); - last_char = strlen(user)-1; - user[last_char] = toupper(user[last_char]); - DEBUG(3, ("Trying username %s\n", user)); - ret = _Get_Pwnam(user); - if (ret) return(ret); - - /* try all combinations up to usernamelevel */ - strlower(user); - ret = uname_string_combinations(user, _Get_Pwnam, usernamelevel); - if (ret) return(ret); - if (allow_change) fstrcpy(user,user2); @@ -268,57 +250,4 @@ BOOL user_in_list(char *user,char *list) return(False); } -/* The functions below have been taken from password.c and slightly modified */ -/**************************************************************************** -apply a function to upper/lower case combinations -of a string and return true if one of them returns true. -try all combinations with N uppercase letters. -offset is the first char to try and change (start with 0) -it assumes the string starts lowercased -****************************************************************************/ -static struct passwd *uname_string_combinations2(char *s,int offset,struct passwd *(*fn)(),int N) -{ - int len = strlen(s); - int i; - struct passwd *ret; - -#ifdef PASSWORD_LENGTH - len = MIN(len,PASSWORD_LENGTH); -#endif - - if (N <= 0 || offset >= len) - return(fn(s)); - - for (i=offset;i<(len-(N-1));i++) - - { - char c = s[i]; - if (!islower(c)) continue; - s[i] = toupper(c); - ret = uname_string_combinations2(s,i+1,fn,N-1); - if(ret) return(ret); - s[i] = c; - } - return(NULL); -} - -/**************************************************************************** -apply a function to upper/lower case combinations -of a string and return true if one of them returns true. -try all combinations with up to N uppercase letters. -offset is the first char to try and change (start with 0) -it assumes the string starts lowercased -****************************************************************************/ -static struct passwd * uname_string_combinations(char *s,struct passwd * (*fn)(),int N) -{ - int n; - struct passwd *ret; - - for (n=1;n<=N;n++) - { - ret = uname_string_combinations2(s,0,fn,n); - if(ret) return(ret); - } - return(NULL); -} diff --git a/source/lib/util.c b/source/lib/util.c index 01e2dae154c..54b2dc08ac8 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -156,7 +156,7 @@ static void check_log_size(void) int maxlog; struct stat st; - if (debug_count++ < 100) return; + if (debug_count++ < 100 || getuid() != 0) return; maxlog = lp_max_log_size() * 1024; if (!dbf || maxlog <= 0) return; @@ -175,7 +175,6 @@ static void check_log_size(void) debug_count=0; } - /******************************************************************* write an debug message on the debugfile. This is called by the DEBUG macro @@ -190,7 +189,8 @@ va_dcl char *format_str; #endif va_list ap; - + int old_errno = errno; + if (stdout_logging) { #ifdef __STDC__ va_start(ap, format_str); @@ -200,6 +200,7 @@ va_dcl #endif vfprintf(dbf,format_str,ap); va_end(ap); + errno = old_errno; return(0); } @@ -207,16 +208,17 @@ va_dcl if (!lp_syslog_only()) #endif { - if (!dbf) - { - int oldumask = umask(022); - dbf = fopen(debugf,"w"); - umask(oldumask); - if (dbf) - setbuf(dbf,NULL); - else - return(0); - } + if (!dbf) { + int oldumask = umask(022); + dbf = fopen(debugf,"w"); + umask(oldumask); + if (dbf) { + setbuf(dbf,NULL); + } else { + errno = old_errno; + return(0); + } + } } #ifdef SYSLOG @@ -273,6 +275,8 @@ va_dcl check_log_size(); + errno = old_errno; + return(0); } @@ -807,145 +811,131 @@ char *attrib_string(int mode) /******************************************************************* case insensitive string compararison ********************************************************************/ -int StrCaseCmp(char *s, char *t) +int StrCaseCmp(const char *s, const char *t) { /* compare until we run out of string, either t or s, or find a difference */ /* We *must* use toupper rather than tolower here due to the asynchronous upper to lower mapping. */ -#if !defined(KANJI_WIN95_COMPATIBILITY) - if(lp_client_code_page() == KANJI_CODEPAGE) +#if defined(KANJI) && !defined(KANJI_WIN95_COMPATIBILITY) + /* Win95 treats full width ascii characters as case sensitive. */ + int diff; + for (;;) { - /* Win95 treats full width ascii characters as case sensitive. */ - int diff; - for (;;) - { - if (!*s || !*t) - return toupper (*s) - toupper (*t); - else if (is_sj_alph (*s) && is_sj_alph (*t)) - { - diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1)); - if (diff) - return diff; - s += 2; - t += 2; - } - else if (is_shift_jis (*s) && is_shift_jis (*t)) - { - diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t); - if (diff) - return diff; - diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1)); - if (diff) - return diff; - s += 2; - t += 2; - } - else if (is_shift_jis (*s)) - return 1; - else if (is_shift_jis (*t)) - return -1; - else - { - diff = toupper (*s) - toupper (*t); - if (diff) - return diff; - s++; - t++; - } - } + if (!*s || !*t) + return toupper (*s) - toupper (*t); + else if (is_sj_alph (*s) && is_sj_alph (*t)) + { + diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1)); + if (diff) + return diff; + s += 2; + t += 2; + } + else if (is_shift_jis (*s) && is_shift_jis (*t)) + { + diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t); + if (diff) + return diff; + diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1)); + if (diff) + return diff; + s += 2; + t += 2; + } + else if (is_shift_jis (*s)) + return 1; + else if (is_shift_jis (*t)) + return -1; + else + { + diff = toupper (*s) - toupper (*t); + if (diff) + return diff; + s++; + t++; + } } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ +#else /* KANJI */ + while (*s && *t && toupper(*s) == toupper(*t)) { - while (*s && *t && toupper(*s) == toupper(*t)) - { - s++; - t++; - } - - return(toupper(*s) - toupper(*t)); + s++; t++; } + + return(toupper(*s) - toupper(*t)); +#endif /* KANJI */ } /******************************************************************* case insensitive string compararison, length limited ********************************************************************/ -int StrnCaseCmp(char *s, char *t, int n) +int StrnCaseCmp(const char *s, const char *t, int n) { /* compare until we run out of string, either t or s, or chars */ /* We *must* use toupper rather than tolower here due to the asynchronous upper to lower mapping. */ -#if !defined(KANJI_WIN95_COMPATIBILITY) - if(lp_client_code_page() == KANJI_CODEPAGE) +#if defined(KANJI) && !defined(KANJI_WIN95_COMPATIBILITY) + /* Win95 treats full width ascii characters as case sensitive. */ + int diff; + for (;n > 0;) { - /* Win95 treats full width ascii characters as case sensitive. */ - int diff; - for (;n > 0;) - { - if (!*s || !*t) - return toupper (*s) - toupper (*t); - else if (is_sj_alph (*s) && is_sj_alph (*t)) - { - diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1)); - if (diff) - return diff; - s += 2; - t += 2; - n -= 2; - } - else if (is_shift_jis (*s) && is_shift_jis (*t)) - { - diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t); - if (diff) - return diff; - diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1)); - if (diff) - return diff; - s += 2; - t += 2; - n -= 2; - } - else if (is_shift_jis (*s)) - return 1; - else if (is_shift_jis (*t)) - return -1; - else - { - diff = toupper (*s) - toupper (*t); - if (diff) - return diff; - s++; - t++; - n--; - } - } - return 0; + if (!*s || !*t) + return toupper (*s) - toupper (*t); + else if (is_sj_alph (*s) && is_sj_alph (*t)) + { + diff = sj_toupper2 (*(s+1)) - sj_toupper2 (*(t+1)); + if (diff) + return diff; + s += 2; + t += 2; + n -= 2; + } + else if (is_shift_jis (*s) && is_shift_jis (*t)) + { + diff = ((int) (unsigned char) *s) - ((int) (unsigned char) *t); + if (diff) + return diff; + diff = ((int) (unsigned char) *(s+1)) - ((int) (unsigned char) *(t+1)); + if (diff) + return diff; + s += 2; + t += 2; + n -= 2; + } + else if (is_shift_jis (*s)) + return 1; + else if (is_shift_jis (*t)) + return -1; + else + { + diff = toupper (*s) - toupper (*t); + if (diff) + return diff; + s++; + t++; + n--; + } } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ + return 0; +#else /* KANJI */ + while (n-- && *s && *t && toupper(*s) == toupper(*t)) { - while (n-- && *s && *t && toupper(*s) == toupper(*t)) - { - s++; - t++; - } + s++; t++; + } - /* not run out of chars - strings are different lengths */ - if (n) - return(toupper(*s) - toupper(*t)); + /* not run out of chars - strings are different lengths */ + if (n) return(toupper(*s) - toupper(*t)); - /* identical up to where we run out of chars, - and strings are same length */ - return(0); - } + /* identical up to where we run out of chars, and strings are same length */ + return(0); +#endif /* KANJI */ } /******************************************************************* compare 2 strings ********************************************************************/ -BOOL strequal(char *s1, char *s2) +BOOL strequal(const char *s1, const char *s2) { if (s1 == s2) return(True); if (!s1 || !s2) return(False); @@ -956,7 +946,7 @@ BOOL strequal(char *s1, char *s2) /******************************************************************* compare 2 strings up to and including the nth char. ******************************************************************/ -BOOL strnequal(char *s1,char *s2,int n) +BOOL strnequal(const char *s1,const char *s2,int n) { if (s1 == s2) return(True); if (!s1 || !s2 || !n) return(False); @@ -982,36 +972,27 @@ BOOL strcsequal(char *s1,char *s2) void strlower(char *s) { while (*s) - { -#if !defined(KANJI_WIN95_COMPATIBILITY) - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - if (is_shift_jis (*s)) - { - if (is_sj_upper (s[0], s[1])) - s[1] = sj_tolower2 (s[1]); - s += 2; - } - else if (is_kana (*s)) - { - s++; - } - else - { - if (isupper(*s)) - *s = tolower(*s); - s++; - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ { +#if defined(KANJI) && !defined(KANJI_WIN95_COMPATIBILITY) + /* Win95 treats full width ascii characters as case sensitive. */ + if (is_shift_jis (*s)) { + if (is_sj_upper (s[0], s[1])) { + s[1] = sj_tolower2 (s[1]); + } + s += 2; + } else if (is_kana (*s)) { + s++; + } else { + if (isupper(*s)) + *s = tolower(*s); + s++; + } +#else /* KANJI */ if (isupper(*s)) - *s = tolower(*s); + *s = tolower(*s); s++; +#endif /* KANJI */ } - } } /******************************************************************* @@ -1020,36 +1001,27 @@ void strlower(char *s) void strupper(char *s) { while (*s) - { -#if !defined(KANJI_WIN95_COMPATIBILITY) - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - if (is_shift_jis (*s)) - { - if (is_sj_lower (s[0], s[1])) - s[1] = sj_toupper2 (s[1]); - s += 2; - } - else if (is_kana (*s)) - { - s++; - } - else - { - if (islower(*s)) - *s = toupper(*s); - s++; - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ { +#if defined(KANJI) && !defined(KANJI_WIN95_COMPATIBILITY) + /* Win95 treats full width ascii characters as case sensitive. */ + if (is_shift_jis (*s)) { + if (is_sj_lower (s[0], s[1])) { + s[1] = sj_toupper2 (s[1]); + } + s += 2; + } else if (is_kana (*s)) { + s++; + } else { + if (islower(*s)) + *s = toupper(*s); + s++; + } +#else /* KANJI */ if (islower(*s)) - *s = toupper(*s); + *s = toupper(*s); s++; +#endif /* KANJI */ } - } } /******************************************************************* @@ -1081,30 +1053,24 @@ BOOL strisnormal(char *s) void string_replace(char *s,char oldc,char newc) { while (*s) - { -#if !defined(KANJI_WIN95_COMPATIBILITY) - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - if (is_shift_jis (*s)) - s += 2; - else if (is_kana (*s)) - s++; - else - { - if (oldc == *s) - *s = newc; - s++; - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ { +#if defined(KANJI) && !defined(KANJI_WIN95_COMPATIBILITY) + /* Win95 treats full width ascii characters as case sensitive. */ + if (is_shift_jis (*s)) { + s += 2; + } else if (is_kana (*s)) { + s++; + } else { + if (oldc == *s) + *s = newc; + s++; + } +#else /* KANJI */ if (oldc == *s) - *s = newc; + *s = newc; s++; +#endif /* KANJI */ } - } } /**************************************************************************** @@ -1488,7 +1454,7 @@ char *GetWd(char *str) if (!sys_getwd(s)) { - DEBUG(0,("Getwd failed, errno %s\n",strerror(errno))); + DEBUG(0,("Getwd failed, errno %d\n",errno)); return (NULL); } @@ -1726,30 +1692,22 @@ does a string have any uppercase chars in it? BOOL strhasupper(char *s) { while (*s) - { -#if !defined(KANJI_WIN95_COMPATIBILITY) - if(lp_client_code_page() == KANJI_CODEPAGE) { - /* Win95 treats full width ascii characters as case sensitive. */ - if (is_shift_jis (*s)) - s += 2; - else if (is_kana (*s)) - s++; - else - { - if (isupper(*s)) - return(True); - s++; - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - if (isupper(*s)) - return(True); +#if defined(KANJI) && !defined(KANJI_WIN95_COMPATIBILITY) + /* Win95 treats full width ascii characters as case sensitive. */ + if (is_shift_jis (*s)) { + s += 2; + } else if (is_kana (*s)) { + s++; + } else { + if (isupper(*s)) return(True); + s++; + } +#else /* KANJI */ + if (isupper(*s)) return(True); s++; +#endif /* KANJI */ } - } return(False); } @@ -1759,38 +1717,24 @@ does a string have any lowercase chars in it? BOOL strhaslower(char *s) { while (*s) - { -#if !defined(KANJI_WIN95_COMPATIBILITY) - if(lp_client_code_page() == KANJI_CODEPAGE) { - /* Win95 treats full width ascii characters as case sensitive. */ - if (is_shift_jis (*s)) - { - if (is_sj_upper (s[0], s[1])) - return(True); - if (is_sj_lower (s[0], s[1])) - return (True); - s += 2; - } - else if (is_kana (*s)) - { - s++; - } - else - { - if (islower(*s)) - return(True); - s++; - } - } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - if (islower(*s)) - return(True); +#if defined(KANJI) && !defined(KANJI_WIN95_COMPATIBILITY) + /* Win95 treats full width ascii characters as case sensitive. */ + if (is_shift_jis (*s)) { + if (is_sj_upper (s[0], s[1])) return(True); + if (is_sj_lower (s[0], s[1])) return (True); + s += 2; + } else if (is_kana (*s)) { + s++; + } else { + if (islower(*s)) return(True); + s++; + } +#else /* KANJI */ + if (islower(*s)) return(True); s++; +#endif /* KANJI */ } - } return(False); } @@ -1800,33 +1744,27 @@ find the number of chars in a string int count_chars(char *s,char c) { int count=0; - -#if !defined(KANJI_WIN95_COMPATIBILITY) - if(lp_client_code_page() == KANJI_CODEPAGE) - { - /* Win95 treats full width ascii characters as case sensitive. */ - while (*s) +#if defined(KANJI) && !defined(KANJI_WIN95_COMPATIBILITY) + /* Win95 treats full width ascii characters as case sensitive. */ + while (*s) { - if (is_shift_jis (*s)) - s += 2; - else - { - if (*s == c) - count++; - s++; - } + if (is_shift_jis (*s)) + s += 2; + else + { + if (*s == c) + count++; + s++; } } - else -#endif /* KANJI_WIN95_COMPATIBILITY */ - { - while (*s) +#else /* KANJI */ + while (*s) { if (*s == c) - count++; + count++; s++; } - } +#endif /* KANJI */ return(count); } @@ -1951,7 +1889,7 @@ int read_udp_socket(int fd,char *buf,int len) bzero((char *)&lastip,sizeof(lastip)); ret = recvfrom(fd,buf,len,0,&sock,&socklen); if (ret <= 0) { - DEBUG(2,("read socket failed. ERRNO=%s\n",strerror(errno))); + DEBUG(2,("read socket failed. ERRNO=%d\n",errno)); return(0); } @@ -2270,11 +2208,10 @@ int read_smb_length(int fd,char *inbuf,int timeout) /**************************************************************************** - read an smb from a fd. Note that the buffer *MUST* be of size - BUFFER_SIZE+SAFETY_MARGIN. + read an smb from a fd and return it's length The timeout is in milli seconds ****************************************************************************/ -BOOL receive_smb(int fd,char *buffer, int timeout) +BOOL receive_smb(int fd,char *buffer,int timeout) { int len,ret; @@ -2301,204 +2238,6 @@ BOOL receive_smb(int fd,char *buffer, int timeout) return(True); } -#ifdef USE_OPLOCKS -/**************************************************************************** - read a message from a udp fd. -The timeout is in milli seconds -****************************************************************************/ -BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout) -{ - struct sockaddr_in from; - int fromlen = sizeof(from); - int32 msg_len = 0; - - if(timeout != 0) - { - struct timeval to; - fd_set fds; - int selrtn; - - FD_ZERO(&fds); - FD_SET(fd,&fds); - - to.tv_sec = timeout / 1000; - to.tv_usec = (timeout % 1000) * 1000; - - selrtn = sys_select(&fds,&to); - - /* Check if error */ - if(selrtn == -1) - { - /* something is wrong. Maybe the socket is dead? */ - smb_read_error = READ_ERROR; - return False; - } - - /* Did we timeout ? */ - if (selrtn == 0) - { - smb_read_error = READ_TIMEOUT; - return False; - } - } - - /* - * Read a loopback udp message. - */ - msg_len = recvfrom(fd, &buffer[UDP_CMD_HEADER_LEN], - buffer_len - UDP_CMD_HEADER_LEN, 0, - (struct sockaddr *)&from, &fromlen); - - if(msg_len < 0) - { - DEBUG(0,("receive_local_message. Error in recvfrom. (%s).\n",strerror(errno))); - return False; - } - - /* Validate message length. */ - if(msg_len > (buffer_len - UDP_CMD_HEADER_LEN)) - { - DEBUG(0,("receive_local_message: invalid msg_len (%d) max can be %d\n", - msg_len, - buffer_len - UDP_CMD_HEADER_LEN)); - return False; - } - - /* Validate message from address (must be localhost). */ - if(from.sin_addr.s_addr != htonl(INADDR_LOOPBACK)) - { - DEBUG(0,("receive_local_message: invalid 'from' address \ -(was %x should be 127.0.0.1\n", from.sin_addr.s_addr)); - return False; - } - - /* Setup the message header */ - SIVAL(buffer,UDP_CMD_LEN_OFFSET,msg_len); - SSVAL(buffer,UDP_CMD_PORT_OFFSET,ntohs(from.sin_port)); - - return True; -} - -/**************************************************************************** - structure to hold a linked list of local udp messages. - for processing. -****************************************************************************/ - -typedef struct _udp_message_list { - struct _udp_message_list *msg_next; - char *msg_buf; - int msg_len; -} udp_message_list; - -static udp_message_list *udp_msg_head = NULL; - -/**************************************************************************** - Function to push a linked list of local udp messages ready - for processing. -****************************************************************************/ -BOOL push_local_message(char *buf, int msg_len) -{ - udp_message_list *msg = (udp_message_list *)malloc(sizeof(udp_message_list)); - - if(msg == NULL) - { - DEBUG(0,("push_local_message: malloc fail (1)\n")); - return False; - } - - msg->msg_buf = (char *)malloc(msg_len); - if(msg->msg_buf == NULL) - { - DEBUG(0,("push_local_message: malloc fail (2)\n")); - free((char *)msg); - return False; - } - - memcpy(msg->msg_buf, buf, msg_len); - msg->msg_len = msg_len; - - msg->msg_next = udp_msg_head; - udp_msg_head = msg; - - return True; -} - -/**************************************************************************** - Do a select on an two fd's - with timeout. - - If a local udp message has been pushed onto the - queue (this can only happen during oplock break - processing) return this first. - - If the first smbfd is ready then read an smb from it. - if the second (loopback UDP) fd is ready then read a message - from it and setup the buffer header to identify the length - and from address. - Returns False on timeout or error. - Else returns True. - -The timeout is in milli seconds -****************************************************************************/ -BOOL receive_message_or_smb(int smbfd, int oplock_fd, - char *buffer, int buffer_len, - int timeout, BOOL *got_smb) -{ - fd_set fds; - int selrtn; - struct timeval to; - - *got_smb = False; - - /* - * Check to see if we already have a message on the udp queue. - * If so - copy and return it. - */ - - if(udp_msg_head) - { - udp_message_list *msg = udp_msg_head; - memcpy(buffer, msg->msg_buf, MIN(buffer_len, msg->msg_len)); - udp_msg_head = msg->msg_next; - - /* Free the message we just copied. */ - free((char *)msg->msg_buf); - free((char *)msg); - return True; - } - - FD_ZERO(&fds); - FD_SET(smbfd,&fds); - FD_SET(oplock_fd,&fds); - - to.tv_sec = timeout / 1000; - to.tv_usec = (timeout % 1000) * 1000; - - selrtn = sys_select(&fds,timeout>0?&to:NULL); - - /* Check if error */ - if(selrtn == -1) { - /* something is wrong. Maybe the socket is dead? */ - smb_read_error = READ_ERROR; - return False; - } - - /* Did we timeout ? */ - if (selrtn == 0) { - smb_read_error = READ_TIMEOUT; - return False; - } - - if (FD_ISSET(smbfd,&fds)) - { - *got_smb = True; - return receive_smb(smbfd, buffer, 0); - } - else - { - return receive_local_message(oplock_fd, buffer, buffer_len, 0); - } -} -#endif /* USE_OPLOCKS */ /**************************************************************************** send an smb to a fd @@ -2607,8 +2346,8 @@ BOOL send_one_packet(char *buf,int len,struct in_addr ip,int port,int type) ret = (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", - inet_ntoa(ip),port,strerror(errno))); + DEBUG(0,("Packet send to %s(%d) failed ERRNO=%d\n", + inet_ntoa(ip),port,errno)); close(out_fd); return(ret); @@ -2860,7 +2599,7 @@ BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2) if (strequal(p1,"*")) return(True); - DEBUG(8,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig)); + DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig)); if (trans2) { fstrcpy(ebase,p1); @@ -2888,7 +2627,7 @@ BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2) matched = do_match(sbase,ebase,case_sig) && (trans2 || do_match(sext,eext,case_sig)); - DEBUG(8,("mask_match returning %d\n", matched)); + DEBUG(5,("mask_match returning %d\n", matched)); return matched; } @@ -3296,8 +3035,26 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) if (res == -1) { DEBUG(0,("socket error\n")); return -1; } - if (type != SOCK_STREAM) return(res); +#ifdef BIND_LOCAL_OUTPUT_SOCKET + { + struct sockaddr_in sock_in; + /* Bind the local part of this socket to the address + given in the socket address parameter. */ + + bzero((char *)&sock_in,sizeof(sock_in)); + putip((char *)&sock_in.sin_addr,(char *)interpret_addr2(lp_socket_address())); + sock_in.sin_port = 0; + sock_in.sin_family = PF_INET; + + if (bind(res, (struct sockaddr * ) &sock_in,sizeof(sock_in)) < 0) + DEBUG(0,("Failed to bind local socket address for output socket. Error was %s\n", + strerror(errno))); + } +#endif /* BIND_LOCAL_OUTPUT_SOCKET */ + + if (type != SOCK_STREAM) return(res); + bzero((char *)&sock_out,sizeof(sock_out)); putip((char *)&sock_out.sin_addr,(char *)addr); @@ -3834,24 +3591,24 @@ char *readdirname(void *p) return(dname); } -/******************************************************************* - Utility function used to decide if the last component - of a path matches a (possibly wildcarded) entry in a namelist. -********************************************************************/ +/* + * Utility function used to decide if the last component + * of a path matches a (possibly wildcarded) entry in a namelist. + */ BOOL is_in_path(char *name, name_compare_entry *namelist) { pstring last_component; char *p; - DEBUG(8, ("is_in_path: %s\n", name)); + DEBUG(5, ("is_in_path: %s\n", name)); /* if we have no list it's obviously not in the path */ if((namelist == NULL ) || ((namelist != NULL) && (namelist[0].name == NULL))) - { - DEBUG(8,("is_in_path: no name list.\n")); + { + DEBUG(5,("is_in_path: no name list.\n")); return False; - } +} /* Get the last component of the unix name. */ p = strrchr(name, '/'); @@ -3865,7 +3622,7 @@ BOOL is_in_path(char *name, name_compare_entry *namelist) /* look for a wildcard match. */ if (mask_match(last_component, namelist->name, case_sensitive, False)) { - DEBUG(8,("is_in_path: mask match succeeded\n")); + DEBUG(5,("is_in_path: mask match succeeded\n")); return True; } } @@ -3874,29 +3631,29 @@ BOOL is_in_path(char *name, name_compare_entry *namelist) if((case_sensitive && (strcmp(last_component, namelist->name) == 0))|| (!case_sensitive && (StrCaseCmp(last_component, namelist->name) == 0))) { - DEBUG(8,("is_in_path: match succeeded\n")); + DEBUG(5,("is_in_path: match succeeded\n")); return True; } } } - DEBUG(8,("is_in_path: match not found\n")); + DEBUG(5,("is_in_path: match not found\n")); return False; } -/******************************************************************* - Strip a '/' separated list into an array of - name_compare_enties structures suitable for - passing to is_in_path(). We do this for - speed so we can pre-parse all the names in the list - and don't do it for each call to is_in_path(). - namelist is modified here and is assumed to be - a copy owned by the caller. - We also check if the entry contains a wildcard to - remove a potentially expensive call to mask_match - if possible. -********************************************************************/ - +/* + * Strip a '/' separated list into an array of + * name_compare_enties structures suitable for + * passing to is_in_path(). We do this for + * speed so we can pre-parse all the names in the list + * and don't do it for each call to is_in_path(). + * namelist is modified here and is assumed to be + * a copy owned by the caller. + * We also check if the entry contains a wildcard to + * remove a potentially expensive call to mask_match + * if possible. + */ + void set_namearray(name_compare_entry **ppname_array, char *namelist) { char *name_end; @@ -4037,7 +3794,7 @@ BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type) #endif - DEBUG(8,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type)); + DEBUG(5,("fcntl_lock %d %d %d %d %d\n",fd,op,(int)offset,(int)count,type)); lock.l_type = type; lock.l_whence = SEEK_SET; @@ -4085,7 +3842,7 @@ BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type) } /* everything went OK */ - DEBUG(8,("Lock call successful\n")); + DEBUG(5,("Lock call successful\n")); return(True); #else @@ -4131,7 +3888,7 @@ void file_unlock(int fd) is the name specified one of my netbios names returns true is it is equal, false otherwise ********************************************************************/ -BOOL is_myname(char *s) +BOOL is_myname(const char *s) { int n; BOOL ret = False; @@ -4182,52 +3939,53 @@ enum remote_arch_types get_remote_arch() return ra_type; } + /******************************************************************* safe string copy into a fstring ********************************************************************/ void fstrcpy(char *dest, char *src) { - int maxlength = sizeof(fstring) - 1; - if (!dest) { - DEBUG(0,("ERROR: NULL dest in fstrcpy\n")); - return; - } + int maxlength = sizeof(fstring) - 1; + if (!dest) { + DEBUG(0,("ERROR: NULL dest in fstrcpy\n")); + return; + } - if (!src) { - *dest = 0; - return; - } - - while (maxlength-- && *src) - *dest++ = *src++; - *dest = 0; - if (*src) { - DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n", - strlen(src))); - } -} + if (!src) { + *dest = 0; + return; + } + + while (maxlength-- && *src) + *dest++ = *src++; + *dest = 0; + if (*src) { + DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n", + strlen(src))); + } +} /******************************************************************* safe string copy into a pstring ********************************************************************/ void pstrcpy(char *dest, char *src) { - int maxlength = sizeof(pstring) - 1; - if (!dest) { - DEBUG(0,("ERROR: NULL dest in pstrcpy\n")); - return; - } - - if (!src) { - *dest = 0; - return; - } - - while (maxlength-- && *src) - *dest++ = *src++; - *dest = 0; - if (*src) { - DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n", - strlen(src))); - } -} + int maxlength = sizeof(pstring) - 1; + if (!dest) { + DEBUG(0,("ERROR: NULL dest in pstrcpy\n")); + return; + } + + if (!src) { + *dest = 0; + return; + } + + while (maxlength-- && *src) + *dest++ = *src++; + *dest = 0; + if (*src) { + DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n", + strlen(src))); + } +} diff --git a/source/libsmb/nmblib.c b/source/libsmb/nmblib.c index 48f988de2a2..29b54a708bc 100644 --- a/source/libsmb/nmblib.c +++ b/source/libsmb/nmblib.c @@ -31,8 +31,8 @@ extern pstring myname; extern struct in_addr ipzero; static struct opcode_names { - char *nmb_opcode_name; - int opcode; + const char *nmb_opcode_name; + int opcode; } nmb_header_opcode_names[] = { { "Query", 0 }, {"Registration", 5 }, @@ -46,7 +46,7 @@ static struct opcode_names { * Lookup a nmb opcode name. ****************************************************************************/ -char *lookup_opcode_name( int opcode ) +const char *lookup_opcode_name( int opcode ) { struct opcode_names *op_namep; int i; diff --git a/source/libsmb/smbdes.c b/source/libsmb/smbdes.c deleted file mode 100644 index 1c38612b739..00000000000 --- a/source/libsmb/smbdes.c +++ /dev/null @@ -1,320 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - - a partial implementation of DES designed for use in the - SMB authentication protocol - - Copyright (C) Andrew Tridgell 1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - - -/* NOTES: - - This code makes no attempt to be fast! In fact, it is a very - slow implementation - - This code is NOT a complete DES implementation. It implements only - the minimum necessary for SMB authentication, as used by all SMB - products (including every copy of Microsoft Windows95 ever sold) - - In particular, it can only do a unchained forward DES pass. This - means it is not possible to use this code for encryption/decryption - of data, instead it is only useful as a "hash" algorithm. - - There is no entry point into this code that allows normal DES operation. - - I believe this means that this code does not come under ITAR - regulations but this is NOT a legal opinion. If you are concerned - about the applicability of ITAR regulations to this code then you - should confirm it for yourself (and maybe let me know if you come - up with a different answer to the one above) -*/ - - - -static int perm1[56] = {57, 49, 41, 33, 25, 17, 9, - 1, 58, 50, 42, 34, 26, 18, - 10, 2, 59, 51, 43, 35, 27, - 19, 11, 3, 60, 52, 44, 36, - 63, 55, 47, 39, 31, 23, 15, - 7, 62, 54, 46, 38, 30, 22, - 14, 6, 61, 53, 45, 37, 29, - 21, 13, 5, 28, 20, 12, 4}; - -static int perm2[48] = {14, 17, 11, 24, 1, 5, - 3, 28, 15, 6, 21, 10, - 23, 19, 12, 4, 26, 8, - 16, 7, 27, 20, 13, 2, - 41, 52, 31, 37, 47, 55, - 30, 40, 51, 45, 33, 48, - 44, 49, 39, 56, 34, 53, - 46, 42, 50, 36, 29, 32}; - -static int perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, - 60, 52, 44, 36, 28, 20, 12, 4, - 62, 54, 46, 38, 30, 22, 14, 6, - 64, 56, 48, 40, 32, 24, 16, 8, - 57, 49, 41, 33, 25, 17, 9, 1, - 59, 51, 43, 35, 27, 19, 11, 3, - 61, 53, 45, 37, 29, 21, 13, 5, - 63, 55, 47, 39, 31, 23, 15, 7}; - -static int perm4[48] = { 32, 1, 2, 3, 4, 5, - 4, 5, 6, 7, 8, 9, - 8, 9, 10, 11, 12, 13, - 12, 13, 14, 15, 16, 17, - 16, 17, 18, 19, 20, 21, - 20, 21, 22, 23, 24, 25, - 24, 25, 26, 27, 28, 29, - 28, 29, 30, 31, 32, 1}; - -static int perm5[32] = { 16, 7, 20, 21, - 29, 12, 28, 17, - 1, 15, 23, 26, - 5, 18, 31, 10, - 2, 8, 24, 14, - 32, 27, 3, 9, - 19, 13, 30, 6, - 22, 11, 4, 25}; - - -static int perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, - 39, 7, 47, 15, 55, 23, 63, 31, - 38, 6, 46, 14, 54, 22, 62, 30, - 37, 5, 45, 13, 53, 21, 61, 29, - 36, 4, 44, 12, 52, 20, 60, 28, - 35, 3, 43, 11, 51, 19, 59, 27, - 34, 2, 42, 10, 50, 18, 58, 26, - 33, 1, 41, 9, 49, 17, 57, 25}; - - -static int sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; - -static int sbox[8][4][16] = { - {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, - {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, - {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, - {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, - - {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, - {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, - {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, - {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, - - {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, - {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, - {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, - {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, - - {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, - {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, - {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, - {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, - - {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, - {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, - {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, - {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, - - {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, - {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, - {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, - {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, - - {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, - {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, - {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, - {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, - - {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, - {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, - {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, - {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}}; - -static void permute(char *out, char *in, int *p, int n) -{ - int i; - for (i=0;i<n;i++) - out[i] = in[p[i]-1]; -} - -static void lshift(char *d, int count, int n) -{ - char out[64]; - int i; - for (i=0;i<n;i++) - out[i] = d[(i+count)%n]; - for (i=0;i<n;i++) - d[i] = out[i]; -} - -static void concat(char *out, char *in1, char *in2, int l1, int l2) -{ - while (l1--) - *out++ = *in1++; - while (l2--) - *out++ = *in2++; -} - -static void xor(char *out, char *in1, char *in2, int n) -{ - int i; - for (i=0;i<n;i++) - out[i] = in1[i] ^ in2[i]; -} - -static void dohash(char *out, char *in, char *key) -{ - int i, j, k; - char pk1[56]; - char c[28]; - char d[28]; - char cd[56]; - char ki[16][48]; - char pd1[64]; - char l[32], r[32]; - char rl[64]; - - permute(pk1, key, perm1, 56); - - for (i=0;i<28;i++) - c[i] = pk1[i]; - for (i=0;i<28;i++) - d[i] = pk1[i+28]; - - for (i=0;i<16;i++) { - lshift(c, sc[i], 28); - lshift(d, sc[i], 28); - - concat(cd, c, d, 28, 28); - permute(ki[i], cd, perm2, 48); - } - - permute(pd1, in, perm3, 64); - - for (j=0;j<32;j++) { - l[j] = pd1[j]; - r[j] = pd1[j+32]; - } - - for (i=0;i<16;i++) { - char er[48]; - char erk[48]; - char b[8][6]; - char cb[32]; - char pcb[32]; - char r2[32]; - - permute(er, r, perm4, 48); - - xor(erk, er, ki[i], 48); - - for (j=0;j<8;j++) - for (k=0;k<6;k++) - b[j][k] = erk[j*6 + k]; - - for (j=0;j<8;j++) { - int m, n; - m = (b[j][0]<<1) | b[j][5]; - - n = (b[j][1]<<3) | (b[j][2]<<2) | (b[j][3]<<1) | b[j][4]; - - for (k=0;k<4;k++) - b[j][k] = (sbox[j][m][n] & (1<<(3-k)))?1:0; - } - - for (j=0;j<8;j++) - for (k=0;k<4;k++) - cb[j*4+k] = b[j][k]; - permute(pcb, cb, perm5, 32); - - xor(r2, l, pcb, 32); - - for (j=0;j<32;j++) - l[j] = r[j]; - - for (j=0;j<32;j++) - r[j] = r2[j]; - } - - concat(rl, r, l, 32, 32); - - permute(out, rl, perm6, 64); -} - -static void str_to_key(unsigned char *str,unsigned char *key) -{ - int i; - - key[0] = str[0]>>1; - key[1] = ((str[0]&0x01)<<6) | (str[1]>>2); - key[2] = ((str[1]&0x03)<<5) | (str[2]>>3); - key[3] = ((str[2]&0x07)<<4) | (str[3]>>4); - key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5); - key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6); - key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7); - key[7] = str[6]&0x7F; - for (i=0;i<8;i++) { - key[i] = (key[i]<<1); - } -} - - -static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key) -{ - int i; - char outb[64]; - char inb[64]; - char keyb[64]; - unsigned char key2[8]; - - str_to_key(key, key2); - - for (i=0;i<64;i++) { - inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0; - keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0; - outb[i] = 0; - } - - dohash(outb, inb, keyb); - - for (i=0;i<8;i++) { - out[i] = 0; - } - - for (i=0;i<64;i++) { - if (outb[i]) - out[i/8] |= (1<<(7-(i%8))); - } -} - -void E_P16(unsigned char *p14,unsigned char *p16) -{ - unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; - smbhash(p16, sp8, p14); - smbhash(p16+8, sp8, p14+7); -} - -void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24) -{ - smbhash(p24, c8, p21); - smbhash(p24+8, c8, p21+7); - smbhash(p24+16, c8, p21+14); -} - - diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c index 27172fd4136..8bb21cfed20 100644 --- a/source/libsmb/smbencrypt.c +++ b/source/libsmb/smbencrypt.c @@ -1,3 +1,4 @@ +#ifdef SMB_PASSWD /* Unix SMB/Netbios implementation. Version 1.9. @@ -21,11 +22,84 @@ */ #include "includes.h" +#include "des.h" +#include "md4.h" extern int DEBUGLEVEL; #include "byteorder.h" +void str_to_key(uchar *str,uchar *key) +{ + void des_set_odd_parity(des_cblock *); + int i; + + key[0] = str[0]>>1; + key[1] = ((str[0]&0x01)<<6) | (str[1]>>2); + key[2] = ((str[1]&0x03)<<5) | (str[2]>>3); + key[3] = ((str[2]&0x07)<<4) | (str[3]>>4); + key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5); + key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6); + key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7); + key[7] = str[6]&0x7F; + for (i=0;i<8;i++) { + key[i] = (key[i]<<1); + } + des_set_odd_parity((des_cblock *)key); +} + +void D1(uchar *k, uchar *d, uchar *out) +{ + des_key_schedule ks; + des_cblock deskey; + + str_to_key(k,(uchar *)deskey); +#ifdef __FreeBSD__ + des_set_key(&deskey,ks); +#else /* __FreeBSD__ */ + des_set_key((des_cblock *)deskey,ks); +#endif /* __FreeBsd */ + des_ecb_encrypt((des_cblock *)d,(des_cblock *)out, ks, DES_DECRYPT); +} + +void E1(uchar *k, uchar *d, uchar *out) +{ + des_key_schedule ks; + des_cblock deskey; + + str_to_key(k,(uchar *)deskey); +#ifdef __FreeBSD__ + des_set_key(&deskey,ks); +#else /* __FreeBsd__ */ + des_set_key((des_cblock *)deskey,ks); +#endif /* __FreeBsd__ */ + des_ecb_encrypt((des_cblock *)d,(des_cblock *)out, ks, DES_ENCRYPT); +} + +void E_P16(uchar *p14,uchar *p16) +{ + uchar sp7[7]; + /* the following constant makes us compatible with other + implementations. Note that publishing this constant does not reduce the + security of the encryption mechanism */ + uchar sp8[] = {0xAA,0xD3,0xB4,0x35,0xB5,0x14,0x4,0xEE}; + uchar x[8]; + + memset(sp7,'\0',7); + + D1(sp7, sp8, x); + E1(p14, x, p16); + E1(p14+7, x, p16+8); +} + +void E_P24(uchar *p21, uchar *c8, uchar *p24) +{ + E1(p21, c8, p24); + E1(p21+7, c8, p24+8); + E1(p21+14, c8, p24+16); +} + + /* This implements the X/Open SMB password encryption It takes a password, a 8 byte "crypt key" and puts 24 bytes of @@ -81,20 +155,28 @@ static int _my_mbstowcs(int16 *dst, uchar *src, int len) void E_md4hash(uchar *passwd, uchar *p16) { - int len; + int i, len; int16 wpwd[129]; - + MDstruct MD; + /* Password cannot be longer than 128 characters */ len = strlen((char *)passwd); if(len > 128) len = 128; /* Password must be converted to NT unicode */ - _my_mbstowcs(wpwd, passwd, len); + _my_mbstowcs( wpwd, passwd, len); wpwd[len] = 0; /* Ensure string is null terminated */ /* Calculate length in bytes */ len = _my_wcslen(wpwd) * sizeof(int16); - - mdfour(p16, (unsigned char *)wpwd, len); + + MDbegin(&MD); + for(i = 0; i + 64 <= len; i += 64) + MDupdate(&MD,wpwd + (i/2), 512); + MDupdate(&MD,wpwd + (i/2),(len-i)*8); + SIVAL(p16,0,MD.buffer[0]); + SIVAL(p16,4,MD.buffer[1]); + SIVAL(p16,8,MD.buffer[2]); + SIVAL(p16,12,MD.buffer[3]); } /* Does the NT MD4 hash then des encryption. */ @@ -109,3 +191,6 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) E_P24(p21, c8, p24); } +#else + void smbencrypt_dummy(void){} +#endif diff --git a/source/locking/locking.c b/source/locking/locking.c index abda5d39d47..461ad5aef0b 100644 --- a/source/locking/locking.c +++ b/source/locking/locking.c @@ -46,7 +46,7 @@ BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset) return(False); return(fcntl_lock(Files[fnum].fd_ptr->fd,F_GETLK,offset,count, - (Files[fnum].can_write?F_WRLCK:F_RDLCK))); + (Files[fnum].can_write?F_WRLCK:F_RDLCK))); } @@ -68,7 +68,7 @@ BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ec if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum)) ok = fcntl_lock(Files[fnum].fd_ptr->fd,F_SETLK,offset,count, - (Files[fnum].can_write?F_WRLCK:F_RDLCK)); + (Files[fnum].can_write?F_WRLCK:F_RDLCK)); if (!ok) { *eclass = ERRDOS; @@ -182,37 +182,37 @@ int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode, file_prev_p = file_scanner_p; while(file_scanner_p) { - if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) ) - { - found = True; - break; - } - else - { - file_prev_p = file_scanner_p ; - file_scanner_p = (share_mode_record *)smb_shm_offset2addr( - file_scanner_p->next_offset); - } + if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) ) + { + found = True; + break; + } + else + { + file_prev_p = file_scanner_p ; + file_scanner_p = (share_mode_record *)smb_shm_offset2addr( + file_scanner_p->next_offset); + } } if(!found) { - DEBUG(5,("get_share_modes (FAST_SHARE_MODES): no entry for \ + DEBUG(5,("get_share_modes (FAST_SHARE_MODES): no entry for \ file dev = %d, ino = %d in hash_bucket %d\n", dev, inode, hash_entry)); - return (0); + return (0); } if(file_scanner_p->locking_version != LOCKING_VERSION) { - DEBUG(0,("ERROR:get_share_modes (FAST_SHARE_MODES): Deleting old share mode \ + DEBUG(0,("ERROR:get_share_modes (FAST_SHARE_MODES): Deleting old share mode \ record due to old locking version %d for file dev = %d, inode = %d in hash \ -bucket %d\n", file_scanner_p->locking_version, dev, inode, hash_entry)); - if(file_prev_p == file_scanner_p) - mode_array[hash_entry] = file_scanner_p->next_offset; - else - file_prev_p->next_offset = file_scanner_p->next_offset; - smb_shm_free(smb_shm_addr2offset(file_scanner_p)); - return (0); +bucket %d\n",file_scanner_p->locking_version, dev, inode, hash_entry)); + if(file_prev_p == file_scanner_p) + mode_array[hash_entry] = file_scanner_p->next_offset; + else + file_prev_p->next_offset = file_scanner_p->next_offset; + smb_shm_free(smb_shm_addr2offset(file_scanner_p)); + return (0); } /* Allocate the old_shares array */ @@ -241,6 +241,7 @@ bucket %d\n", file_scanner_p->locking_version, dev, inode, hash_entry)); { /* Delete this share mode entry */ share_mode_entry *delete_entry_p = entry_scanner_p; + int share_mode = entry_scanner_p->share_mode; if(entry_prev_p == entry_scanner_p) { @@ -271,7 +272,7 @@ for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries DEBUG(0,("get_share_modes (FAST_SHARE_MODES): process %d no longer exists and \ it left a share mode entry with mode 0x%X for file dev = %d, ino = %d in hash \ bucket %d (number of entries now = %d)\n", - pid, entry_scanner_p->share_mode, dev, inode, hash_entry, + pid, share_mode, dev, inode, hash_entry, file_scanner_p->num_share_mode_entries)); smb_shm_free(smb_shm_addr2offset(delete_entry_p)); @@ -283,10 +284,6 @@ bucket %d (number of entries now = %d)\n", */ share_array[num_entries_copied].pid = entry_scanner_p->pid; share_array[num_entries_copied].share_mode = entry_scanner_p->share_mode; -#ifdef USE_OPLOCKS - share_array[num_entries_copied].op_port = entry_scanner_p->op_port; - share_array[num_entries_copied].op_type = entry_scanner_p->op_type; -#endif /* USE_OPLOCKS */ memcpy(&share_array[num_entries_copied].time, &entry_scanner_p->time, sizeof(struct timeval)); num_entries_copied++; @@ -316,7 +313,8 @@ hash bucket %d has a share mode record but no entries - deleting\n", } DEBUG(5,("get_share_modes (FAST_SHARE_MODES): file with dev %d, inode %d in \ -hash bucket %d returning %d entries\n", dev, inode, hash_entry, num_entries_copied)); +hash bucket %d returning %d entries\n", dev, inode, hash_entry, + num_entries_copied)); return(num_entries_copied); } @@ -364,17 +362,17 @@ void del_share_mode(share_lock_token token, int fnum) while(file_scanner_p) { - if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) ) - { - found = True; - break; - } - else - { - file_prev_p = file_scanner_p ; - file_scanner_p = (share_mode_record *) - smb_shm_offset2addr(file_scanner_p->next_offset); - } + if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) ) + { + found = True; + break; + } + else + { + file_prev_p = file_scanner_p ; + file_scanner_p = (share_mode_record *) + smb_shm_offset2addr(file_scanner_p->next_offset); + } } if(!found) @@ -386,20 +384,20 @@ inode %d in hash bucket %d\n", dev, inode, hash_entry)); if(file_scanner_p->locking_version != LOCKING_VERSION) { - DEBUG(0,("ERROR: del_share_modes (FAST_SHARE_MODES): Deleting old share mode \ + DEBUG(0,("ERROR: del_share_modes (FAST_SHARE_MODES): Deleting old share mode \ record due to old locking version %d for file dev %d, inode %d hash bucket %d\n", file_scanner_p->locking_version, dev, inode, hash_entry )); - if(file_prev_p == file_scanner_p) - mode_array[hash_entry] = file_scanner_p->next_offset; - else - file_prev_p->next_offset = file_scanner_p->next_offset; - smb_shm_free(smb_shm_addr2offset(file_scanner_p)); - return; + if(file_prev_p == file_scanner_p) + mode_array[hash_entry] = file_scanner_p->next_offset; + else + file_prev_p->next_offset = file_scanner_p->next_offset; + smb_shm_free(smb_shm_addr2offset(file_scanner_p)); + return; } found = False; entry_scanner_p = (share_mode_entry*)smb_shm_offset2addr( - file_scanner_p->share_mode_entries); + file_scanner_p->share_mode_entries); entry_prev_p = entry_scanner_p; while(entry_scanner_p) { @@ -444,15 +442,15 @@ for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries /* If we deleted the last share mode entry then remove the share mode record. */ if(file_scanner_p->num_share_mode_entries == 0) - { + { DEBUG(2,("del_share_modes (FAST_SHARE_MODES): num entries = 0, deleting share_mode \ record dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry)); if(file_prev_p == file_scanner_p) - mode_array[hash_entry] = file_scanner_p->next_offset; + mode_array[hash_entry] = file_scanner_p->next_offset; else - file_prev_p->next_offset = file_scanner_p->next_offset; + file_prev_p->next_offset = file_scanner_p->next_offset; smb_shm_free(smb_shm_addr2offset(file_scanner_p)); - } + } } else { @@ -464,7 +462,7 @@ dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry)); /******************************************************************* set the share mode of a file. Return False on fail, True on success. ********************************************************************/ -BOOL set_share_mode(share_lock_token token, int fnum, uint16 port, uint16 op_type) +BOOL set_share_mode(share_lock_token token, int fnum) { files_struct *fs_p = &Files[fnum]; int32 dev, inode; @@ -496,17 +494,17 @@ BOOL set_share_mode(share_lock_token token, int fnum, uint16 port, uint16 op_typ while(file_scanner_p) { - if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) ) - { - found = True; - break; - } - else - { - file_prev_p = file_scanner_p ; - file_scanner_p = (share_mode_record *) - smb_shm_offset2addr(file_scanner_p->next_offset); - } + if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) ) + { + found = True; + break; + } + else + { + file_prev_p = file_scanner_p ; + file_scanner_p = (share_mode_record *) + smb_shm_offset2addr(file_scanner_p->next_offset); + } } if(!found) @@ -555,10 +553,6 @@ inode %d in hash bucket %d\n", fs_p->name, dev, inode, hash_entry)); new_entry_p->pid = getpid(); new_entry_p->share_mode = fs_p->share_mode; -#ifdef USE_OPLOCKS - new_entry_p->op_port = port; - new_entry_p->op_type = op_type; -#endif /* USE_OPLOCKS */ memcpy( (char *)&new_entry_p->time, (char *)&fs_p->open_time, sizeof(struct timeval)); /* Chain onto the share_mode_record */ @@ -584,121 +578,6 @@ for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries return(True); } -/******************************************************************* -Remove an oplock port and mode entry from a share mode. -********************************************************************/ -BOOL remove_share_oplock(int fnum, share_lock_token token) -{ -#ifdef USE_OPLOCKS - uint32 dev, inode; - smb_shm_offset_t *mode_array; - unsigned int hash_entry; - share_mode_record *file_scanner_p; - share_mode_record *file_prev_p; - share_mode_entry *entry_scanner_p; - share_mode_entry *entry_prev_p; - BOOL found = False; - int pid = getpid(); - - dev = Files[fnum].fd_ptr->dev; - inode = Files[fnum].fd_ptr->inode; - - hash_entry = HASH_ENTRY(dev, inode); - - if(hash_entry > lp_shmem_hash_size() ) - { - DEBUG(0, - ("PANIC ERROR:remove_share_oplock (FAST_SHARE_MODES): hash_entry %d too large \ -(max = %d)\n", - hash_entry, lp_shmem_hash_size() )); - return False; - } - - mode_array = (smb_shm_offset_t *)smb_shm_offset2addr(smb_shm_get_userdef_off()); - - if(mode_array[hash_entry] == NULL_OFFSET) - { - DEBUG(0,("PANIC ERROR:remove_share_oplock (FAST_SHARE_MODES): hash bucket %d empty\n", - hash_entry)); - return False; - } - - file_scanner_p = (share_mode_record *)smb_shm_offset2addr(mode_array[hash_entry]); - file_prev_p = file_scanner_p; - - while(file_scanner_p) - { - if( (file_scanner_p->st_dev == dev) && (file_scanner_p->st_ino == inode) ) - { - found = True; - break; - } - else - { - file_prev_p = file_scanner_p ; - file_scanner_p = (share_mode_record *) - smb_shm_offset2addr(file_scanner_p->next_offset); - } - } - - if(!found) - { - DEBUG(0,("ERROR:remove_share_oplock (FAST_SHARE_MODES): no entry found for dev %d, \ -inode %d in hash bucket %d\n", dev, inode, hash_entry)); - return False; - } - - if(file_scanner_p->locking_version != LOCKING_VERSION) - { - DEBUG(0,("ERROR: remove_share_oplock (FAST_SHARE_MODES): Deleting old share mode \ -record due to old locking version %d for file dev %d, inode %d hash bucket %d\n", - file_scanner_p->locking_version, dev, inode, hash_entry )); - if(file_prev_p == file_scanner_p) - mode_array[hash_entry] = file_scanner_p->next_offset; - else - file_prev_p->next_offset = file_scanner_p->next_offset; - smb_shm_free(smb_shm_addr2offset(file_scanner_p)); - return False; - } - - found = False; - entry_scanner_p = (share_mode_entry*)smb_shm_offset2addr( - file_scanner_p->share_mode_entries); - entry_prev_p = entry_scanner_p; - while(entry_scanner_p) - { - if( (pid == entry_scanner_p->pid) && - (entry_scanner_p->share_mode == Files[fnum].share_mode) && - (memcmp(&entry_scanner_p->time, - &Files[fnum].open_time,sizeof(struct timeval)) == 0) ) - { - /* Delete the oplock info. */ - entry_scanner_p->op_port = 0; - entry_scanner_p->op_type = 0; - found = True; - break; - } - else - { - entry_prev_p = entry_scanner_p; - entry_scanner_p = (share_mode_entry *) - smb_shm_offset2addr(entry_scanner_p->next_share_mode_entry); - } - } - - if(!found) - { - DEBUG(0,("ERROR: remove_share_oplock (FAST_SHARE_MODES): No oplock granted share \ -mode record found dev = %d, inode = %d in hash bucket %d\n", dev, inode, hash_entry)); - return False; - } - - return True; -#else /* USE_OPLOCKS */ - return False; -#endif /* USE_OPLOCKS */ -} - #else /* FAST_SHARE_MODES */ /* SHARE MODE LOCKS USING SLOW DESCRIPTION FILES */ @@ -725,50 +604,88 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok { pstring fname; int fd; + int ret = True; *ptok = (share_lock_token)-1; if(!share_name(cnum, dev, inode, fname)) return False; + /* we need to do this as root */ + become_root(0); + { int old_umask; - unbecome_user(); + BOOL gotlock = False; old_umask = umask(0); + + /* + * There was a race condition in the original slow share mode code. + * A smbd could open a share mode file, and before getting + * the lock, another smbd could delete the last entry for + * the share mode file and delete the file entry from the + * directory. Thus this smbd would be left with a locked + * share mode fd attached to a file that no longer had a + * directory entry. Thus another smbd would think that + * there were no outstanding opens on the file. To fix + * this we now check we can do a stat() call on the filename + * before allowing the lock to proceed, and back out completely + * and try the open again if we cannot. + * Jeremy Allison (jallison@whistle.com). + */ + + do + { + struct stat dummy_stat; #ifdef SECURE_SHARE_MODES - fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0600); + fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0600); #else /* SECURE_SHARE_MODES */ - fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0666); + fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0666); #endif /* SECURE_SHARE_MODES */ + + if(fd < 0) + { + DEBUG(0,("ERROR lock_share_entry: failed to open share file %s. Error was %s\n", + fname, strerror(errno))); + ret = False; + break; + } + + /* At this point we have an open fd to the share mode file. + Lock the first byte exclusively to signify a lock. */ + if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False) + { + DEBUG(0,("ERROR lock_share_entry: fcntl_lock failed with %s\n", + strerror(errno))); + close(fd); + ret = False; + break; + } + + /* + * If we cannot stat the filename, the file was deleted between + * the open and the lock call. Back out and try again. + */ + + if(stat(fname, &dummy_stat)!=0) + { + DEBUG(2,("lock_share_entry: Re-issuing open on %s to fix race. Error was %s\n", + fname, strerror(errno))); + close(fd); + } + else + gotlock = True; + } while(!gotlock); + umask(old_umask); - if(!become_user(cnum,Connections[cnum].vuid)) - { - DEBUG(0,("lock_share_entry: Can't become connected user!\n")); - close(fd); - return False; - } - /* We need to change directory back to the connection root. */ - if (ChDir(Connections[cnum].connectpath) != 0) - { - DEBUG(0,("lock_share_entry: Can't change directory to %s (%s)\n", - Connections[cnum].connectpath, strerror(errno))); - close(fd); - return False; - } } - /* At this point we have an open fd to the share mode file. - Lock the first byte exclusively to signify a lock. */ - if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False) - { - DEBUG(0,("ERROR lock_share_entry: fcntl_lock failed with %s\n", - strerror(errno))); - close(fd); - return False; - } + *ptok = (share_lock_token)fd; - *ptok = (share_lock_token)fd; - return True; + /* return to our previous privilage level */ + unbecome_root(0); + + return ret; } /******************************************************************* @@ -795,31 +712,21 @@ BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token tok /******************************************************************* Force a share file to be deleted. ********************************************************************/ - static int delete_share_file( int cnum, char *fname ) { - unbecome_user(); - if(unlink(fname) != 0) - { - DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n", - fname, strerror(errno))); - } - - DEBUG(5,("delete_share_file: Deleted share file %s\n", fname)); - - if(!become_user(cnum,Connections[cnum].vuid)) - { - DEBUG(0,("delete_share_file: Can't become connected user!\n")); - return -1; - } - /* We need to change directory back to the connection root. */ - if (ChDir(Connections[cnum].connectpath) != 0) - { - DEBUG(0,("delete_share_file: Can't change directory to %s (%s)\n", - Connections[cnum].connectpath, strerror(errno))); - return -1; - } - return 0; + /* the share file could be owned by anyone, so do this as root */ + become_root(0); + + if(unlink(fname) != 0) { + DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n", + fname, strerror(errno))); + } else { + DEBUG(5,("delete_share_file: Deleted share file %s\n", fname)); + } + + unbecome_root(0); + + return 0; } /******************************************************************* @@ -873,11 +780,10 @@ for share file %s (%s)\n", fname, strerror(errno))); return -1; } - if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION) { + if (IVAL(buf,0) != LOCKING_VERSION) { DEBUG(0,("ERROR: read_share_file: share file %s has incorrect \ -locking version (was %d, should be %d).\n",fname, - IVAL(buf,SMF_VERSION_OFFSET), LOCKING_VERSION)); - if(buf) +locking version (was %d, should be %d).\n",fname, IVAL(buf,0), LOCKING_VERSION)); + if(buf) free(buf); delete_share_file(cnum, fname); return -1; @@ -885,13 +791,13 @@ locking version (was %d, should be %d).\n",fname, /* Sanity check for file contents */ size = sb.st_size; - size -= SMF_HEADER_LENGTH; /* Remove the header */ + size -= 10; /* Remove the header */ /* Remove the filename component. */ - size -= SVAL(buf, SMF_FILENAME_LEN_OFFSET); + size -= SVAL(buf, 8); - /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */ - if((size % SMF_ENTRY_LENGTH) != 0) + /* The remaining size must be a multiple of 16 - error if not. */ + if((size % 16) != 0) { DEBUG(0,("ERROR: read_share_file: share file %s is an incorrect length - \ deleting it.\n", fname)); @@ -936,7 +842,7 @@ int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode, 4 - tv_usec 8 - share_mode 12 - pid - 16 - oplock port (if oplocks in use) - 2 bytes. + */ share_name(cnum, dev, inode, fname); @@ -951,7 +857,7 @@ int get_share_modes(int cnum, share_lock_token token, uint32 dev, uint32 inode, if(new_file == True) return 0; - num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET); + num_entries = IVAL(buf,4); DEBUG(5,("get_share_modes: share file %s has %d share mode entries.\n", fname, num_entries)); @@ -986,30 +892,26 @@ for share file %d\n", num_entries, fname)); } num_entries_copied = 0; - base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET); + base = buf + 10 + SVAL(buf,8); for( i = 0; i < num_entries; i++) { int pid; - char *p = base + (i*SMF_ENTRY_LENGTH); + char *p = base + (i*16); - pid = IVAL(p,SME_PID_OFFSET); + pid = IVAL(p,12); if(!process_exists(pid)) { DEBUG(0,("get_share_modes: process %d no longer exists and \ it left a share mode entry with mode 0x%X in share file %s\n", - pid, IVAL(p,SME_SHAREMODE_OFFSET), fname)); + pid, IVAL(p,8), fname)); continue; } - share_array[num_entries_copied].time.tv_sec = IVAL(p,SME_SEC_OFFSET); - share_array[num_entries_copied].time.tv_usec = IVAL(p,SME_USEC_OFFSET); - share_array[num_entries_copied].share_mode = IVAL(p,SME_SHAREMODE_OFFSET); + share_array[num_entries_copied].time.tv_sec = IVAL(p,0); + share_array[num_entries_copied].time.tv_usec = IVAL(p,4); + share_array[num_entries_copied].share_mode = IVAL(p,8); share_array[num_entries_copied].pid = pid; -#ifdef USE_OPLOCKS - share_array[num_entries_copied].op_port = SVAL(p,SME_PORT_OFFSET); - share_array[num_entries_copied].op_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET); -#endif /* USE_OPLOCKS */ num_entries_copied++; } @@ -1045,22 +947,18 @@ position 0 for share mode file %s (%s)\n", fname, strerror(errno))); return 0; } - SIVAL(buf, SMF_NUM_ENTRIES_OFFSET, num_entries_copied); + SIVAL(buf, 4, num_entries_copied); for( i = 0; i < num_entries_copied; i++) { - char *p = base + (i*SMF_ENTRY_LENGTH); - - SIVAL(p,SME_PID_OFFSET,share_array[i].pid); - SIVAL(p,SME_SHAREMODE_OFFSET,share_array[i].share_mode); - SIVAL(p,SME_SEC_OFFSET,share_array[i].time.tv_sec); - SIVAL(p,SME_USEC_OFFSET,share_array[i].time.tv_usec); -#ifdef USE_OPLOCKS - SSVAL(p,SME_PORT_OFFSET,share_array[i].op_port); - SSVAL(p,SME_OPLOCK_TYPE_OFFSET,share_array[i].op_type); -#endif /* USE_OPLOCKS */ + char *p = base + (i*16); + + SIVAL(p,12,share_array[i].pid); + SIVAL(p,8,share_array[i].share_mode); + SIVAL(p,0,share_array[i].time.tv_sec); + SIVAL(p,4,share_array[i].time.tv_usec); } - newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries_copied); + newsize = (base - buf) + (16*num_entries_copied); if(write(fd, buf, newsize) != newsize) { DEBUG(0,("ERROR: get_share_modes: failed to re-write share \ @@ -1130,7 +1028,7 @@ void del_share_mode(share_lock_token token, int fnum) return; } - num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET); + num_entries = IVAL(buf,4); DEBUG(5,("del_share_mode: share file %s has %d share mode entries.\n", fname, num_entries)); @@ -1160,16 +1058,14 @@ for share file %d\n", num_entries, fname)); we have set - delete it. */ - base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET); + base = buf + 10 + SVAL(buf,8); for(i = 0; i < num_entries; i++) { - char *p = base + (i*SMF_ENTRY_LENGTH); + char *p = base + (i*16); - if((IVAL(p,SME_SEC_OFFSET) != fs_p->open_time.tv_sec) || - (IVAL(p,SME_USEC_OFFSET) != fs_p->open_time.tv_usec) || - (IVAL(p,SME_SHAREMODE_OFFSET) != fs_p->share_mode) || - (IVAL(p,SME_PID_OFFSET) != pid)) + if((IVAL(p,0) != fs_p->open_time.tv_sec) || (IVAL(p,4) != fs_p->open_time.tv_usec) || + (IVAL(p,8) != fs_p->share_mode) || (IVAL(p,12) != pid)) continue; DEBUG(5,("del_share_mode: deleting entry number %d (of %d) from the share file %s\n", @@ -1177,7 +1073,7 @@ for share file %d\n", num_entries, fname)); /* Remove this entry. */ if(i != num_entries - 1) - memcpy(p, p + SMF_ENTRY_LENGTH, (num_entries - i - 1)*SMF_ENTRY_LENGTH); + memcpy(p, p + 16, (num_entries - i - 1)*16); deleted = True; break; @@ -1192,7 +1088,7 @@ for share file %d\n", num_entries, fname)); } num_entries--; - SIVAL(buf,SMF_NUM_ENTRIES_OFFSET, num_entries); + SIVAL(buf,4, num_entries); if(num_entries == 0) { @@ -1207,23 +1103,23 @@ for share file %d\n", num_entries, fname)); /* Re-write the file - and truncate it at the correct point. */ if(lseek(fd, 0, SEEK_SET) != 0) - { - DEBUG(0,("ERROR: del_share_mode: lseek failed to reset to \ + { + DEBUG(0,("ERROR: del_share_mode: lseek failed to reset to \ position 0 for share mode file %s (%s)\n", fname, strerror(errno))); - if(buf) - free(buf); - return; - } + if(buf) + free(buf); + return; + } - newsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries); + newsize = (base - buf) + (16*num_entries); if(write(fd, buf, newsize) != newsize) - { - DEBUG(0,("ERROR: del_share_mode: failed to re-write share \ + { + DEBUG(0,("ERROR: del_share_mode: failed to re-write share \ mode file %s (%s)\n", fname, strerror(errno))); - if(buf) - free(buf); - return; - } + if(buf) + free(buf); + return; + } /* Now truncate the file at this point. */ if(ftruncate(fd, newsize) != 0) { @@ -1238,7 +1134,7 @@ mode file %s to size %d (%s)\n", fname, newsize, strerror(errno))); /******************************************************************* set the share mode of a file ********************************************************************/ -BOOL set_share_mode(share_lock_token token,int fnum, uint16 port, uint16 op_type) +BOOL set_share_mode(share_lock_token token,int fnum) { files_struct *fs_p = &Files[fnum]; pstring fname; @@ -1266,10 +1162,9 @@ BOOL set_share_mode(share_lock_token token,int fnum, uint16 port, uint16 op_type int size = sb.st_size; /* Allocate space for the file plus one extra entry */ - if((buf = (char *)malloc(sb.st_size + SMF_ENTRY_LENGTH)) == NULL) + if((buf = (char *)malloc(sb.st_size + 16)) == NULL) { - DEBUG(0,("set_share_mode: malloc for file size %d fail !\n", - sb.st_size + SMF_ENTRY_LENGTH)); + DEBUG(0,("set_share_mode: malloc for file size %d fail !\n", sb.st_size + 16)); return False; } @@ -1291,21 +1186,20 @@ to 0 for share file %s (%s)\n", fname, strerror(errno))); return False; } - if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION) + if (IVAL(buf,0) != LOCKING_VERSION) { DEBUG(0,("ERROR: set_share_mode: share file %s has incorrect \ -locking version (was %d, should be %d).\n",fname, IVAL(buf,SMF_VERSION_OFFSET), - LOCKING_VERSION)); +locking version (was %d, should be %d).\n",fname, IVAL(buf,0), LOCKING_VERSION)); if(buf) free(buf); delete_share_file(fs_p->cnum, fname); return False; } - size -= (SMF_HEADER_LENGTH + SVAL(buf, SMF_FILENAME_LEN_OFFSET)); /* Remove the header */ + size -= (10 + SVAL(buf, 8)); /* Remove the header */ - /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */ - if((size % SMF_ENTRY_LENGTH) != 0) + /* The remaining size must be a multiple of 16 - error if not. */ + if((size % 16) != 0) { DEBUG(0,("ERROR: set_share_mode: share file %s is an incorrect length - \ deleting it.\n", fname)); @@ -1319,33 +1213,28 @@ deleting it.\n", fname)); else { /* New file - just use a single_entry. */ - if((buf = (char *)malloc(SMF_HEADER_LENGTH + - strlen(fs_p->name) + 1 + SMF_ENTRY_LENGTH)) == NULL) + if((buf = (char *)malloc(10 + strlen(fs_p->name) + 1 + 16)) == NULL) { DEBUG(0,("ERROR: set_share_mode: malloc failed for single entry.\n")); return False; } - SIVAL(buf,SMF_VERSION_OFFSET,LOCKING_VERSION); - SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,0); - SSVAL(buf,SMF_FILENAME_LEN_OFFSET,strlen(fs_p->name) + 1); - strcpy(buf + SMF_HEADER_LENGTH, fs_p->name); + SIVAL(buf,0,LOCKING_VERSION); + SIVAL(buf,4,0); + SSVAL(buf,8,strlen(fs_p->name) + 1); + strcpy(buf + 10, fs_p->name); } - num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET); - header_size = SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET); - p = buf + header_size + (num_entries * SMF_ENTRY_LENGTH); - SIVAL(p,SME_SEC_OFFSET,fs_p->open_time.tv_sec); - SIVAL(p,SME_USEC_OFFSET,fs_p->open_time.tv_usec); - SIVAL(p,SME_SHAREMODE_OFFSET,fs_p->share_mode); - SIVAL(p,SME_PID_OFFSET,pid); -#ifdef USE_OPLOCKS - SSVAL(p,SME_PORT_OFFSET,port); - SSVAL(p,SME_OPLOCK_TYPE_OFFSET,op_type); -#endif /* USE_OPLOCKS */ + num_entries = IVAL(buf,4); + header_size = 10 + SVAL(buf,8); + p = buf + header_size + (num_entries * 16); + SIVAL(p,0,fs_p->open_time.tv_sec); + SIVAL(p,4,fs_p->open_time.tv_usec); + SIVAL(p,8,fs_p->share_mode); + SIVAL(p,12,pid); num_entries++; - SIVAL(buf,SMF_NUM_ENTRIES_OFFSET,num_entries); + SIVAL(buf,4,num_entries); if(lseek(fd, 0, SEEK_SET) != 0) { @@ -1356,8 +1245,7 @@ deleting it.\n", fname)); return False; } - if (write(fd,buf,header_size + (num_entries*SMF_ENTRY_LENGTH)) != - (header_size + (num_entries*SMF_ENTRY_LENGTH))) + if (write(fd,buf,header_size + (num_entries*16)) != (header_size + (num_entries*16))) { DEBUG(2,("ERROR: set_share_mode: Failed to write share file %s - \ deleting it (%s).\n",fname, strerror(errno))); @@ -1368,11 +1256,10 @@ deleting it (%s).\n",fname, strerror(errno))); } /* Now truncate the file at this point - just for safety. */ - if(ftruncate(fd, header_size + (SMF_ENTRY_LENGTH*num_entries))!= 0) + if(ftruncate(fd, header_size + (16*num_entries))!= 0) { DEBUG(0,("ERROR: set_share_mode: failed to ftruncate share \ -mode file %s to size %d (%s)\n", fname, header_size + (SMF_ENTRY_LENGTH*num_entries), - strerror(errno))); +mode file %s to size %d (%s)\n", fname, header_size + (16*num_entries), strerror(errno))); if(buf) free(buf); return False; @@ -1386,126 +1273,4 @@ mode 0x%X pid=%d\n",fname,fs_p->share_mode,pid)); return True; } - -/******************************************************************* -Remove an oplock port and mode entry from a share mode. -********************************************************************/ -BOOL remove_share_oplock(int fnum, share_lock_token token) -{ -#ifdef USE_OPLOCKS - pstring fname; - int fd = (int)token; - char *buf = 0; - char *base = 0; - int num_entries; - int fsize; - int i; - files_struct *fs_p = &Files[fnum]; - int pid; - BOOL found = False; - BOOL new_file; - - share_name(fs_p->cnum, fs_p->fd_ptr->dev, - fs_p->fd_ptr->inode, fname); - - if(read_share_file( fs_p->cnum, fd, fname, &buf, &new_file) != 0) - { - DEBUG(0,("ERROR: remove_share_oplock: Failed to read share file %s\n", - fname)); - return False; - } - - if(new_file == True) - { - DEBUG(0,("ERROR: remove_share_oplock: share file %s is new (size zero), \ -deleting it.\n", fname)); - delete_share_file(fs_p->cnum, fname); - return False; - } - - num_entries = IVAL(buf,SMF_NUM_ENTRIES_OFFSET); - - DEBUG(5,("remove_share_oplock: share file %s has %d share mode entries.\n", - fname, num_entries)); - - /* PARANOIA TEST */ - if(num_entries < 0) - { - DEBUG(0,("PANIC ERROR:remove_share_oplock: num_share_mode_entries < 0 (%d) \ -for share file %d\n", num_entries, fname)); - return False; - } - - if(num_entries == 0) - { - /* No entries - just delete the file. */ - DEBUG(0,("remove_share_oplock: share file %s has no share mode entries - deleting.\n", - fname)); - if(buf) - free(buf); - delete_share_file(fs_p->cnum, fname); - return False; - } - - pid = getpid(); - - /* Go through the entries looking for the particular one - we have set - remove the oplock settings on it. - */ - - base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET); - - for(i = 0; i < num_entries; i++) - { - char *p = base + (i*SMF_ENTRY_LENGTH); - - if((IVAL(p,SME_SEC_OFFSET) != fs_p->open_time.tv_sec) || - (IVAL(p,SME_USEC_OFFSET) != fs_p->open_time.tv_usec) || - (IVAL(p,SME_SHAREMODE_OFFSET) != fs_p->share_mode) || - (IVAL(p,SME_PID_OFFSET) != pid)) - continue; - - DEBUG(5,("remove_share_oplock: clearing oplock on entry number %d (of %d) \ -from the share file %s\n", i, num_entries, fname)); - - SSVAL(p,SME_PORT_OFFSET,0); - SSVAL(p,SME_OPLOCK_TYPE_OFFSET,0); - found = True; - break; - } - - if(!found) - { - DEBUG(0,("remove_share_oplock: entry not found in share file %s\n", fname)); - if(buf) - free(buf); - return False; - } - - /* Re-write the file - and truncate it at the correct point. */ - if(lseek(fd, 0, SEEK_SET) != 0) - { - DEBUG(0,("ERROR: remove_share_oplock: lseek failed to reset to \ -position 0 for share mode file %s (%s)\n", fname, strerror(errno))); - if(buf) - free(buf); - return False; - } - - fsize = (base - buf) + (SMF_ENTRY_LENGTH*num_entries); - if(write(fd, buf, fsize) != fsize) - { - DEBUG(0,("ERROR: remove_share_oplock: failed to re-write share \ -mode file %s (%s)\n", fname, strerror(errno))); - if(buf) - free(buf); - return False; - } - - return True; - -#else /* USE_OPLOCKS */ - return False; -#endif /* USE_OPLOCKS */ -} #endif /* FAST_SHARE_MODES */ diff --git a/source/locking/shmem.c b/source/locking/shmem.c index bbb11f215a0..fcd9f3ad0d7 100644 --- a/source/locking/shmem.c +++ b/source/locking/shmem.c @@ -94,7 +94,7 @@ static BOOL smb_shm_global_lock(void) /* Do an exclusive wait lock on the first byte of the file */ if (fcntl_lock(smb_shm_fd, F_SETLKW, 0, 1, F_WRLCK) == False) { - DEBUG(0,("ERROR smb_shm_global_lock : fcntl_lock failed with code %s\n",strerror(errno))); + DEBUG(0,("ERROR smb_shm_global_lock : fcntl_lock failed with code %d\n",errno)); smb_shm_times_locked--; return False; } @@ -128,7 +128,7 @@ static BOOL smb_shm_global_unlock(void) /* Do a wait unlock on the first byte of the file */ if (fcntl_lock(smb_shm_fd, F_SETLKW, 0, 1, F_UNLCK) == False) { - DEBUG(0,("ERROR smb_shm_global_unlock : fcntl_lock failed with code %s\n",strerror(errno))); + DEBUG(0,("ERROR smb_shm_global_unlock : fcntl_lock failed with code %d\n",errno)); smb_shm_times_locked++; return False; } @@ -178,7 +178,7 @@ static BOOL smb_shm_register_process(char *processreg_file, pid_t pid, BOOL *oth #endif /* SECURE_SHARE_MODES */ if ( smb_shm_processes_fd < 0 ) { - DEBUG(0,("ERROR smb_shm_register_process : processreg_file open failed with code %s\n",strerror(errno))); + DEBUG(0,("ERROR smb_shm_register_process : processreg_file open failed with code %d\n",errno)); return False; } @@ -208,7 +208,7 @@ static BOOL smb_shm_register_process(char *processreg_file, pid_t pid, BOOL *oth } if (nb_read < 0) { - DEBUG(0,("ERROR smb_shm_register_process : processreg_file read failed with code %s\n",strerror(errno))); + DEBUG(0,("ERROR smb_shm_register_process : processreg_file read failed with code %d\n",errno)); close(smb_shm_processes_fd); return False; } @@ -220,7 +220,7 @@ static BOOL smb_shm_register_process(char *processreg_file, pid_t pid, BOOL *oth lseek(smb_shm_processes_fd, free_slot, SEEK_SET); if(write(smb_shm_processes_fd, &pid, sizeof(pid)) < 0) { - DEBUG(0,("ERROR smb_shm_register_process : processreg_file write failed with code %s\n",strerror(errno))); + DEBUG(0,("ERROR smb_shm_register_process : processreg_file write failed with code %d\n",errno)); close(smb_shm_processes_fd); return False; } @@ -246,7 +246,7 @@ static BOOL smb_shm_unregister_process(char *processreg_file, pid_t pid) umask(old_umask); if ( smb_shm_processes_fd < 0 ) { - DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file open failed with code %s\n",strerror(errno))); + DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file open failed with code %d\n",errno)); return False; } @@ -262,7 +262,7 @@ static BOOL smb_shm_unregister_process(char *processreg_file, pid_t pid) erased_slot = lseek(smb_shm_processes_fd, seek_back, SEEK_CUR); if(write(smb_shm_processes_fd, &other_pid, sizeof(other_pid)) < 0) { - DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file write failed with code %s\n",strerror(errno))); + DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file write failed with code %d\n",errno)); close(smb_shm_processes_fd); return False; } @@ -273,7 +273,7 @@ static BOOL smb_shm_unregister_process(char *processreg_file, pid_t pid) } if (nb_read < 0) { - DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file read failed with code %s\n",strerror(errno))); + DEBUG(0,("ERROR smb_shm_unregister_process : processreg_file read failed with code %d\n",errno)); close(smb_shm_processes_fd); return False; } @@ -399,7 +399,7 @@ BOOL smb_shm_open( char *file_name, int size) umask(old_umask); if ( smb_shm_fd < 0 ) { - DEBUG(0,("ERROR smb_shm_open : open failed with code %s\n",strerror(errno))); + DEBUG(0,("ERROR smb_shm_open : open failed with code %d\n",errno)); return False; } @@ -411,7 +411,7 @@ BOOL smb_shm_open( char *file_name, int size) if( (filesize = lseek(smb_shm_fd, 0, SEEK_END)) < 0) { - DEBUG(0,("ERROR smb_shm_open : lseek failed with code %s\n",strerror(errno))); + DEBUG(0,("ERROR smb_shm_open : lseek failed with code %d\n",errno)); smb_shm_global_unlock(); close(smb_shm_fd); return False; @@ -446,7 +446,7 @@ BOOL smb_shm_open( char *file_name, int size) /* we just created a new one, or are the first opener, lets set it size */ if( ftruncate(smb_shm_fd, size) <0) { - DEBUG(0,("ERROR smb_shm_open : ftruncate failed with code %s\n",strerror(errno))); + DEBUG(0,("ERROR smb_shm_open : ftruncate failed with code %d\n",errno)); smb_shm_unregister_process(smb_shm_processreg_name, getpid()); smb_shm_global_unlock(); close(smb_shm_fd); @@ -471,7 +471,7 @@ BOOL smb_shm_open( char *file_name, int size) /* WARNING, smb_shm_header_p can be different for different processes mapping the same file ! */ if (smb_shm_header_p == (struct SmbShmHeader *)(-1)) { - DEBUG(0,("ERROR smb_shm_open : mmap failed with code %s\n",strerror(errno))); + DEBUG(0,("ERROR smb_shm_open : mmap failed with code %d\n",errno)); smb_shm_unregister_process(smb_shm_processreg_name, getpid()); smb_shm_global_unlock(); close(smb_shm_fd); @@ -514,7 +514,7 @@ BOOL smb_shm_close( void ) if ((smb_shm_header_p != NULL) && (munmap((caddr_t)smb_shm_header_p, smb_shm_header_p->total_size) < 0)) { - DEBUG(0,("ERROR smb_shm_close : munmap failed with code %s\n",strerror(errno))); + DEBUG(0,("ERROR smb_shm_close : munmap failed with code %d\n",errno)); } smb_shm_global_lock(); @@ -733,7 +733,7 @@ BOOL smb_shm_set_userdef_off(smb_shm_offset_t userdef_off) return True; } -void *smb_shm_offset2addr(smb_shm_offset_t offset) +void * smb_shm_offset2addr(smb_shm_offset_t offset) { if (offset == NULL_OFFSET ) return (void *)(0); @@ -778,7 +778,7 @@ BOOL smb_shm_lock_hash_entry( unsigned int entry) /* Do an exclusive wait lock on the 4 byte region mapping into this entry */ if (fcntl_lock(smb_shm_fd, F_SETLKW, start, sizeof(smb_shm_offset_t), F_WRLCK) == False) { - DEBUG(0,("ERROR smb_shm_lock_hash_entry : fcntl_lock failed with code %s\n",strerror(errno))); + DEBUG(0,("ERROR smb_shm_lock_hash_entry : fcntl_lock failed with code %d\n",errno)); return False; } @@ -809,7 +809,7 @@ BOOL smb_shm_unlock_hash_entry( unsigned int entry ) /* Do a wait lock on the 4 byte region mapping into this entry */ if (fcntl_lock(smb_shm_fd, F_SETLKW, start, sizeof(smb_shm_offset_t), F_UNLCK) == False) { - DEBUG(0,("ERROR smb_shm_unlock_hash_entry : fcntl_lock failed with code %s\n",strerror(errno))); + DEBUG(0,("ERROR smb_shm_unlock_hash_entry : fcntl_lock failed with code %d\n",errno)); return False; } diff --git a/source/md4.h b/source/md4.h new file mode 100644 index 00000000000..3f60d75fe3c --- /dev/null +++ b/source/md4.h @@ -0,0 +1,58 @@ +/* + This code is from rfc1186. +*/ + + /* + ** ******************************************************************** + ** md4.h -- Header file for implementation of ** + ** MD4 Message Digest Algorithm ** + ** Updated: 2/13/90 by Ronald L. Rivest ** + ** (C) 1990 RSA Data Security, Inc. ** + ** ******************************************************************** + */ + + /* MDstruct is the data structure for a message digest computation. + */ + typedef struct { + unsigned int buffer[4]; /* Holds 4-word result of MD computation */ + unsigned char count[8]; /* Number of bits processed so far */ + unsigned int done; /* Nonzero means MD computation finished */ + } MDstruct, *MDptr; + + /* MDbegin(MD) + + + + ** Input: MD -- an MDptr + ** Initialize the MDstruct prepatory to doing a message digest + ** computation. + */ + extern void MDbegin(); + + /* MDupdate(MD,X,count) + ** Input: MD -- an MDptr + ** X -- a pointer to an array of unsigned characters. + ** count -- the number of bits of X to use (an unsigned int). + ** Updates MD using the first "count" bits of X. + ** The array pointed to by X is not modified. + ** If count is not a multiple of 8, MDupdate uses high bits of + ** last byte. + ** This is the basic input routine for a user. + ** The routine terminates the MD computation when count < 512, so + ** every MD computation should end with one call to MDupdate with a + ** count less than 512. Zero is OK for a count. + */ + extern void MDupdate(); + + /* MDprint(MD) + ** Input: MD -- an MDptr + ** Prints message digest buffer MD as 32 hexadecimal digits. + ** Order is from low-order byte of buffer[0] to high-order byte + ** of buffer[3]. + ** Each byte is printed with high-order hexadecimal digit first. + */ + extern void MDprint(); + + /* + ** End of md4.h + */ diff --git a/source/nameannounce.c b/source/nameannounce.c index d3344ebd478..84e3ad3fa77 100644 --- a/source/nameannounce.c +++ b/source/nameannounce.c @@ -383,6 +383,7 @@ void announce_master(time_t t) for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d)) { + struct work_record *work; for (work = d->workgrouplist; work; work = work->next) { if (AM_MASTER(work)) @@ -436,10 +437,9 @@ workgroup %s\n", am_master, work->work_group)); /* We are the WINS server - query ourselves for the dmb name. */ struct nmb_name netb_name; + struct subnet_record *d = 0; struct name_record *nr = 0; - - d = NULL; - + make_nmb_name(&netb_name, name, type, scope); if ((nr = find_name_search(&d, &netb_name, FIND_WINS, ipzero)) == 0) diff --git a/source/nameelect.c b/source/nameelect.c index 5fd1a4bdf2e..5c156a312ed 100644 --- a/source/nameelect.c +++ b/source/nameelect.c @@ -636,6 +636,7 @@ void unbecome_domain_master(struct subnet_record *d, struct work_record *work, { work = find_workgroupstruct(d, myworkgroup, False); + announce_server(d, work, work->work_group, myname, 0, 0); /* Remove the name entry without any NetBIOS traffic as that's how it was registered. */ remove_name_entry(d,work->work_group,0x1b); @@ -670,6 +671,8 @@ void unbecome_logon_server(struct subnet_record *d, struct work_record *work, work->log_state = LOGON_NONE; + /* announce ourselves as no longer active as a master browser. */ + announce_server(d, work, work->work_group, myname, 0, 0); remove_name_entry(d,work->work_group,0x1c); } } diff --git a/source/param/loadparm.c b/source/param/loadparm.c index fb656aa627f..510a661dc39 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -49,11 +49,6 @@ #include "includes.h" -/* Set default coding system for KANJI if none specified in Makefile. */ -#ifndef KANJI -#define KANJI "sjis" -#endif /* KANJI */ - BOOL bLoaded = False; extern int DEBUGLEVEL; @@ -102,7 +97,9 @@ int keepalive=0; extern BOOL use_getwd_cache; extern int extra_time_offset; +#ifdef KANJI extern int coding_system; +#endif /* * This structure describes global (ie., server-wide) parameters. @@ -146,7 +143,6 @@ typedef struct int max_mux; int max_packet; int pwordlevel; - int unamelevel; int deadtime; int maxprotocol; int security; @@ -257,7 +253,6 @@ typedef struct BOOL bLocking; BOOL bStrictLocking; BOOL bShareModes; - BOOL bOpLocks; BOOL bOnlyUser; BOOL bMangledNames; BOOL bWidelinks; @@ -267,7 +262,6 @@ typedef struct BOOL *copymap; BOOL bDeleteReadonly; BOOL bFakeOplocks; - BOOL bDeleteVetoFiles; char dummy[3]; /* for alignment */ } service; @@ -339,7 +333,6 @@ static service sDefault = True, /* bLocking */ False, /* bStrictLocking */ True, /* bShareModes */ - True, /* bOpLocks */ False, /* bOnlyUser */ True, /* bMangledNames */ True, /* bWidelinks */ @@ -349,7 +342,6 @@ static service sDefault = NULL, /* copymap */ False, /* bDeleteReadonly */ False, /* bFakeOplocks */ - False, /* bDeleteVetoFiles */ "" /* dummy */ }; @@ -375,7 +367,9 @@ static BOOL handle_case(char *pszParmValue,int *val); static BOOL handle_printing(char *pszParmValue,int *val); static BOOL handle_character_set(char *pszParmValue,int *val); static BOOL handle_announce_as(char *pszParmValue, int *val); +#ifdef KANJI static BOOL handle_coding_system(char *pszParmValue,int *val); +#endif /* KANJI */ static void set_default_server_announce_type(void); @@ -452,14 +446,15 @@ struct parm_struct {"max packet", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL}, {"packet size", P_INTEGER, P_GLOBAL, &Globals.max_packet, NULL}, {"password level", P_INTEGER, P_GLOBAL, &Globals.pwordlevel, NULL}, - {"username level", P_INTEGER, P_GLOBAL, &Globals.unamelevel, NULL}, {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL}, {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL}, {"time offset", P_INTEGER, P_GLOBAL, &extra_time_offset, NULL}, {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL}, {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL}, {"shared file entries", P_INTEGER, P_GLOBAL, &Globals.shmem_hash_size, NULL}, +#ifdef KANJI {"coding system", P_INTEGER, P_GLOBAL, &coding_system, handle_coding_system}, +#endif /* KANJI */ {"client code page", P_INTEGER, P_GLOBAL, &Globals.client_code_page, NULL}, {"os level", P_INTEGER, P_GLOBAL, &Globals.os_level, NULL}, {"max ttl", P_INTEGER, P_GLOBAL, &Globals.max_ttl, NULL}, @@ -527,7 +522,6 @@ struct parm_struct {"set directory", P_BOOLREV, P_LOCAL, &sDefault.bNo_set_dir, NULL}, {"status", P_BOOL, P_LOCAL, &sDefault.status, NULL}, {"hide dot files", P_BOOL, P_LOCAL, &sDefault.bHideDotFiles, NULL}, - {"delete veto files",P_BOOL, P_LOCAL, &sDefault.bDeleteVetoFiles, NULL}, {"veto files", P_STRING, P_LOCAL, &sDefault.szVetoFiles, NULL}, {"hide files", P_STRING, P_LOCAL, &sDefault.szHideFiles, NULL}, {"guest only", P_BOOL, P_LOCAL, &sDefault.bGuest_only, NULL}, @@ -543,7 +537,6 @@ struct parm_struct {"locking", P_BOOL, P_LOCAL, &sDefault.bLocking, NULL}, {"strict locking", P_BOOL, P_LOCAL, &sDefault.bStrictLocking, NULL}, {"share modes", P_BOOL, P_LOCAL, &sDefault.bShareModes, NULL}, - {"oplocks", P_BOOL, P_LOCAL, &sDefault.bOpLocks, NULL}, {"only user", P_BOOL, P_LOCAL, &sDefault.bOnlyUser, NULL}, {"wide links", P_BOOL, P_LOCAL, &sDefault.bWidelinks, NULL}, {"follow symlinks", P_BOOL, P_LOCAL, &sDefault.bSymlinks, NULL}, @@ -606,7 +599,11 @@ static void init_globals(void) #endif string_set(&Globals.szPasswdChat,"*old*password* %o\\n *new*password* %n\\n *new*password* %n\\n *changed*"); string_set(&Globals.szWorkGroup, WORKGROUP); +#ifdef SMB_PASSWD string_set(&Globals.szPasswdProgram, SMB_PASSWD); +#else + string_set(&Globals.szPasswdProgram, "/bin/passwd"); +#endif string_set(&Globals.szPrintcapname, PRINTCAP_NAME); string_set(&Globals.szLockDir, LOCKDIR); string_set(&Globals.szRootdir, "/"); @@ -624,7 +621,6 @@ static void init_globals(void) Globals.max_mux = 50; /* This is *needed* for profile support. */ Globals.lpqcachetime = 10; Globals.pwordlevel = 0; - Globals.unamelevel = 0; Globals.deadtime = 0; Globals.max_log_size = 5000; Globals.maxprotocol = PROTOCOL_NT1; @@ -650,7 +646,9 @@ static void init_globals(void) Globals.bNISHomeMap = False; string_set(&Globals.szNISHomeMapName, "auto.home"); #endif +#ifdef KANJI coding_system = interpret_coding_system (KANJI, SJIS_CODE); +#endif /* KANJI */ Globals.client_code_page = DEFAULT_CLIENT_CODE_PAGE; Globals.bTimeServer = False; @@ -871,7 +869,6 @@ FN_GLOBAL_INTEGER(lp_maxmux,&Globals.max_mux) FN_GLOBAL_INTEGER(lp_maxpacket,&Globals.max_packet) FN_GLOBAL_INTEGER(lp_keepalive,&keepalive) FN_GLOBAL_INTEGER(lp_passwordlevel,&Globals.pwordlevel) -FN_GLOBAL_INTEGER(lp_usernamelevel,&Globals.unamelevel) FN_GLOBAL_INTEGER(lp_readsize,&Globals.ReadSize) FN_GLOBAL_INTEGER(lp_shmem_size,&Globals.shmem_size) FN_GLOBAL_INTEGER(lp_shmem_hash_size,&Globals.shmem_hash_size) @@ -938,7 +935,6 @@ FN_LOCAL_BOOL(lp_map_archive,bMap_archive) FN_LOCAL_BOOL(lp_locking,bLocking) FN_LOCAL_BOOL(lp_strict_locking,bStrictLocking) FN_LOCAL_BOOL(lp_share_modes,bShareModes) -FN_LOCAL_BOOL(lp_oplocks,bOpLocks) FN_LOCAL_BOOL(lp_onlyuser,bOnlyUser) FN_LOCAL_BOOL(lp_manglednames,bMangledNames) FN_LOCAL_BOOL(lp_widelinks,bWidelinks) @@ -947,7 +943,6 @@ FN_LOCAL_BOOL(lp_syncalways,bSyncAlways) FN_LOCAL_BOOL(lp_map_system,bMap_system) FN_LOCAL_BOOL(lp_delete_readonly,bDeleteReadonly) FN_LOCAL_BOOL(lp_fake_oplocks,bFakeOplocks) -FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles) FN_LOCAL_INTEGER(lp_create_mode,iCreate_mask) FN_LOCAL_INTEGER(lp_force_create_mode,iCreate_force_mode) @@ -972,6 +967,8 @@ static void copy_service( service *pserviceDest, static BOOL service_ok(int iService); static BOOL do_parameter(char *pszParmName, char *pszParmValue); static BOOL do_section(char *pszSectionName); +static void dump_globals(void); +static void dump_a_service(service *pService); static void init_copymap(service *pservice); @@ -1142,8 +1139,6 @@ BOOL lp_add_printer(char *pszPrintername, int iDefaultService) iSERVICE(i).bRead_only = False; /* No share modes on printer services. */ iSERVICE(i).bShareModes = False; - /* No oplocks on printer services. */ - iSERVICE(i).bOpLocks = False; /* Printer services must be printable. */ iSERVICE(i).bPrint_ok = True; @@ -1425,6 +1420,7 @@ BOOL lp_file_list_changed(void) return(False); } +#ifdef KANJI /*************************************************************************** handle the interpretation of the coding system parameter *************************************************************************/ @@ -1433,6 +1429,7 @@ static BOOL handle_coding_system(char *pszParmValue,int *val) *val = interpret_coding_system(pszParmValue,*val); return(True); } +#endif /* KANJI */ /*************************************************************************** handle the interpretation of the character set system parameter @@ -1613,15 +1610,18 @@ static void init_copymap(service *pservice) /*************************************************************************** -Process a parameter for a particular service number. If snum < 0 -then assume we are in the globals +Process a parameter. ***************************************************************************/ -BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue) +static BOOL do_parameter(char *pszParmName, char *pszParmValue) { int parmnum; void *parm_ptr=NULL; /* where we are going to store the result */ void *def_ptr=NULL; + if (!bInGlobalSection && bGlobalOnly) return(True); + + DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue)); + parmnum = map_parameter(pszParmName); if (parmnum < 0) @@ -1633,33 +1633,37 @@ BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue) def_ptr = parm_table[parmnum].ptr; /* we might point at a service, the default service or a global */ - if (snum < 0) { + if (bInGlobalSection) parm_ptr = def_ptr; - } else { - if (parm_table[parmnum].class == P_GLOBAL) { + else + { + if (parm_table[parmnum].class == P_GLOBAL) + { DEBUG(0,( "Global parameter %s found in service section!\n",pszParmName)); return(True); } - parm_ptr = ((char *)pSERVICE(snum)) + PTR_DIFF(def_ptr,&sDefault); - } + parm_ptr = ((char *)pSERVICE(iServiceIndex)) + PTR_DIFF(def_ptr,&sDefault); + } - if (snum >= 0) { - int i; - if (!iSERVICE(snum).copymap) - init_copymap(pSERVICE(snum)); - - /* this handles the aliases - set the copymap for other entries with - the same data pointer */ - for (i=0;parm_table[i].label;i++) - if (parm_table[i].ptr == parm_table[parmnum].ptr) - iSERVICE(snum).copymap[i] = False; - } + if (!bInGlobalSection) + { + int i; + if (!iSERVICE(iServiceIndex).copymap) + init_copymap(pSERVICE(iServiceIndex)); + + /* this handles the aliases - set the copymap for other entries with + the same data pointer */ + for (i=0;parm_table[i].label;i++) + if (parm_table[i].ptr == parm_table[parmnum].ptr) + iSERVICE(iServiceIndex).copymap[i] = False; + } /* if it is a special case then go ahead */ - if (parm_table[parmnum].special) { - parm_table[parmnum].special(pszParmValue,parm_ptr); - return(True); - } + if (parm_table[parmnum].special) + { + parm_table[parmnum].special(pszParmValue,parm_ptr); + return(True); + } /* now switch on the type of variable it is */ switch (parm_table[parmnum].type) @@ -1708,105 +1712,48 @@ BOOL lp_do_parameter(int snum, char *pszParmName, char *pszParmValue) } /*************************************************************************** -Process a parameter. -***************************************************************************/ -static BOOL do_parameter(char *pszParmName, char *pszParmValue) -{ - if (!bInGlobalSection && bGlobalOnly) return(True); - - DEBUG(3,("doing parameter %s = %s\n",pszParmName,pszParmValue)); - - return lp_do_parameter(bInGlobalSection?-2:iServiceIndex, pszParmName, pszParmValue); -} - - -/*************************************************************************** print a parameter of the specified type ***************************************************************************/ -static void print_parameter(parm_type type,void *ptr, FILE *f) +static void print_parameter(parm_type type,void *ptr) { switch (type) { case P_BOOL: - fprintf(f,"%s",BOOLSTR(*(BOOL *)ptr)); + printf("%s",BOOLSTR(*(BOOL *)ptr)); break; case P_BOOLREV: - fprintf(f,"%s",BOOLSTR(! *(BOOL *)ptr)); + printf("%s",BOOLSTR(! *(BOOL *)ptr)); break; case P_INTEGER: - fprintf(f,"%d",*(int *)ptr); + printf("%d",*(int *)ptr); break; case P_CHAR: - fprintf(f,"%c",*(char *)ptr); + printf("%c",*(char *)ptr); break; case P_OCTAL: - fprintf(f,"0%o",*(int *)ptr); + printf("0%o",*(int *)ptr); break; case P_GSTRING: case P_UGSTRING: if ((char *)ptr) - fprintf(f,"%s",(char *)ptr); + printf("%s",(char *)ptr); break; case P_STRING: case P_USTRING: if (*(char **)ptr) - fprintf(f,"%s",*(char **)ptr); + printf("%s",*(char **)ptr); break; } } /*************************************************************************** -print a parameter of the specified type -***************************************************************************/ -static void parameter_string(parm_type type,void *ptr,char *s) -{ - s[0] = 0; - - switch (type) - { - case P_BOOL: - sprintf(s, "%s",BOOLSTR(*(BOOL *)ptr)); - break; - - case P_BOOLREV: - sprintf(s, "%s",BOOLSTR(! *(BOOL *)ptr)); - break; - - case P_INTEGER: - sprintf(s, "%d",*(int *)ptr); - break; - - case P_CHAR: - sprintf(s, "%c",*(char *)ptr); - break; - - case P_OCTAL: - sprintf(s, "0%o",*(int *)ptr); - break; - - case P_GSTRING: - case P_UGSTRING: - if ((char *)ptr) - sprintf(s, "%s",(char *)ptr); - break; - - case P_STRING: - case P_USTRING: - if (*(char **)ptr) - sprintf(s, "%s",*(char **)ptr); - break; - } -} - - -/*************************************************************************** check if two parameters are equal ***************************************************************************/ static BOOL equal_parameter(parm_type type,void *ptr1,void *ptr2) @@ -1898,32 +1845,32 @@ static BOOL do_section(char *pszSectionName) /*************************************************************************** Display the contents of the global structure. ***************************************************************************/ -static void dump_globals(FILE *f) +static void dump_globals(void) { int i; - fprintf(f, "# Global parameters\n"); + printf("Global parameters:\n"); for (i=0;parm_table[i].label;i++) if (parm_table[i].class == P_GLOBAL && parm_table[i].ptr && (i == 0 || (parm_table[i].ptr != parm_table[i-1].ptr))) { - fprintf(f,"\t%s = ",parm_table[i].label); - print_parameter(parm_table[i].type,parm_table[i].ptr, f); - fprintf(f,"\n"); + printf("\t%s: ",parm_table[i].label); + print_parameter(parm_table[i].type,parm_table[i].ptr); + printf("\n"); } } /*************************************************************************** Display the contents of a single services record. ***************************************************************************/ -static void dump_a_service(service *pService, FILE *f) +static void dump_a_service(service *pService) { int i; if (pService == &sDefault) - fprintf(f,"\n\n# Default service parameters\n"); + printf("\nDefault service parameters:\n"); else - fprintf(f,"\n[%s]\n",pService->szService); + printf("\nService parameters [%s]:\n",pService->szService); for (i=0;parm_table[i].label;i++) if (parm_table[i].class == P_LOCAL && @@ -1937,69 +1884,14 @@ static void dump_a_service(service *pService, FILE *f) ((char *)pService) + pdiff, ((char *)&sDefault) + pdiff)) { - fprintf(f,"\t%s = ",parm_table[i].label); + printf("\t%s: ",parm_table[i].label); print_parameter(parm_table[i].type, - ((char *)pService) + pdiff, f); - fprintf(f,"\n"); + ((char *)pService) + pdiff); + printf("\n"); } } } - -/*************************************************************************** -return info about the next service in a service. snum==-1 gives the default -serice and snum==-2 gives the globals - -return 0 when out of parameters -***************************************************************************/ -int lp_next_parameter(int snum, int *i, char *label, - char *value, int allparameters) -{ - if (snum == -2) { - /* do the globals */ - for (;parm_table[*i].label;(*i)++) - if (parm_table[*i].class == P_GLOBAL && - parm_table[*i].ptr && - (*parm_table[*i].label != '-') && - ((*i) == 0 || - (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) { - strcpy(label, parm_table[*i].label); - parameter_string(parm_table[*i].type, - parm_table[*i].ptr, - value); - (*i)++; - return 1; - } - return 0; - } else { - service *pService = (snum==-1?&sDefault:pSERVICE(snum)); - - for (;parm_table[*i].label;(*i)++) - if (parm_table[*i].class == P_LOCAL && - parm_table[*i].ptr && - (*parm_table[*i].label != '-') && - ((*i) == 0 || - (parm_table[*i].ptr != parm_table[(*i)-1].ptr))) { - int pdiff = PTR_DIFF(parm_table[*i].ptr,&sDefault); - - if (snum == -1 || allparameters || - !equal_parameter(parm_table[*i].type, - ((char *)pService) + pdiff, - ((char *)&sDefault) + pdiff)) { - strcpy(label, parm_table[*i].label); - parameter_string(parm_table[*i].type, - ((char *)pService) + pdiff, - value); - (*i)++; - return 1; - } - } - } - - return 0; -} - - #if 0 /*************************************************************************** Display the contents of a single copy structure. @@ -2108,7 +2000,7 @@ void lp_killunused(BOOL (*snumused)(int )) { int i; for (i=0;i<iNumServices;i++) - if (VALID(i) && (!snumused || !snumused(i))) + if (VALID(i) && !snumused(i)) { iSERVICE(i).valid = False; free_service(pSERVICE(i)); @@ -2171,13 +2063,13 @@ int lp_numservices(void) /*************************************************************************** Display the contents of the services array in human-readable form. ***************************************************************************/ -void lp_dump(FILE *f) +void lp_dump(void) { int iService; - dump_globals(f); + dump_globals(); - dump_a_service(&sDefault, f); + dump_a_service(&sDefault); for (iService = 0; iService < iNumServices; iService++) { @@ -2185,12 +2077,11 @@ void lp_dump(FILE *f) { if (iSERVICE(iService).szService[0] == '\0') break; - dump_a_service(pSERVICE(iService), f); + dump_a_service(pSERVICE(iService)); } } } - /*************************************************************************** Return the number of the service with the given name, or -1 if it doesn't exist. Note that this is a DIFFERENT ANIMAL from the internal function @@ -2268,38 +2159,6 @@ static void set_default_server_announce_type() #endif } - -/******************************************************************* -rename a service -********************************************************************/ -void lp_rename_service(int snum, char *new_name) -{ - string_set(&pSERVICE(snum)->szService, new_name); -} - -/******************************************************************* -remove a service -********************************************************************/ -void lp_remove_service(int snum) -{ - pSERVICE(snum)->valid = False; -} - -/******************************************************************* -copy a service -********************************************************************/ -void lp_copy_service(int snum, char *new_name) -{ - char *oldname = lp_servicename(snum); - do_section(new_name); - if (snum >= 0) { - snum = lp_servicenumber(new_name); - if (snum >= 0) - lp_do_parameter(snum, "copy", oldname); - } -} - - /******************************************************************* Get the default server type we will announce as via nmbd. ********************************************************************/ @@ -2354,4 +2213,3 @@ int lp_minor_announce_version(void) minor_version = atoi(p); return minor_version; } - diff --git a/source/param/params.c b/source/param/params.c index 8c41eef789f..0fdde0348ff 100644 --- a/source/param/params.c +++ b/source/param/params.c @@ -1,567 +1,326 @@ -/* -------------------------------------------------------------------------- ** - * Microsoft Network Services for Unix, AKA., Andrew Tridgell's SAMBA. - * - * This module Copyright (C) 1990, 1991, 1992, 1993, 1994 Karl Auer - * - * Rewritten almost completely by Christopher R. Hertel - * at the University of Minnesota, September, 1997. - * This module Copyright (C) 1997 by the University of Minnesota - * -------------------------------------------------------------------------- ** - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * -------------------------------------------------------------------------- ** - * - * Module name: params - * - * -------------------------------------------------------------------------- ** - * - * This module performs lexical analysis and initial parsing of a - * Windows-like parameter file. It recognizes and handles four token - * types: section-name, parameter-name, parameter-value, and - * end-of-file. Comments and line continuation are handled - * internally. - * - * The entry point to the module is function pm_process(). This - * function opens the source file, calls the Parse() function to parse - * the input, and then closes the file when either the EOF is reached - * or a fatal error is encountered. - * - * A sample parameter file might look like this: - * - * [section one] - * parameter one = value string - * parameter two = another value - * [section two] - * new parameter = some value or t'other - * - * The parameter file is divided into sections by section headers: - * section names enclosed in square brackets (eg. [section one]). - * Each section contains parameter lines, each of which consist of a - * parameter name and value delimited by an equal sign. Roughly, the - * syntax is: - * - * <file> :== { <section> } EOF - * - * <section> :== <section header> { <parameter line> } - * - * <section header> :== '[' NAME ']' - * - * <parameter line> :== NAME '=' VALUE '\n' - * - * Blank lines and comment lines are ignored. Comment lines are lines - * beginning with either a semicolon (';') or a pound sign ('#'). - * - * All whitespace in section names and parameter names is compressed - * to single spaces. Leading and trailing whitespace is stipped from - * both names and values. - * - * Only the first equals sign in a parameter line is significant. - * Parameter values may contain equals signs, square brackets and - * semicolons. Internal whitespace is retained in parameter values, - * with the exception of the '\r' character, which is stripped for - * historic reasons. Parameter names may not start with a left square - * bracket, an equal sign, a pound sign, or a semicolon, because these - * are used to identify other tokens. - * - * -------------------------------------------------------------------------- ** - */ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Parameter loading utlities + Copyright (C) Karl Auer 1993,1994,1997 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/************************************************************************** +PARAMS.C + +Copyright (C) 1990, 1991, 1992, 1993, 1994 Karl Auer + +This module provides for streamlines retrieval of information from a +Windows-like parameter files. There is a function which will search for +all sections in the file and call a specified function with each. There is +a similar function which will call a specified function for all parameters +in a section. The idea is that you pass the addresses of suitable functions +to a single function in this module which will then enumerate all sections, +and within each section all parameters, to your program. + +Parameter files contain text lines (newline delimited) which consist of +either a section name in square brackets or a parameter name, delimited +from the parameter value by an equals sign. Blank lines or lines where the +first non-whitespace character is a colon are ignored. All whitespace in +section names and parameter names is compressed to single spaces. Leading +and trailing whitespace on parameter names and parameter values is stripped. + +Only the first equals sign in a parameter line is significant - parameter +values may contain equals signs, square brackets and semicolons. Internal +whitespace is retained in parameter values. Parameter names may not start +with a square bracket, an equals sign or a semicolon, for obvious reasons. + +A sample parameter file might look like this: + +[things] +this=1 +that=2 +[other things] +the other = 3 + +**************************************************************************/ #include "includes.h" -/* -------------------------------------------------------------------------- ** - * Constants... - */ - -#define BUFR_INC 1024 - - -/* -------------------------------------------------------------------------- ** - * Variables... - * - * DEBUGLEVEL - The ubiquitous DEBUGLEVEL. This determines which DEBUG() - * messages will be produced. - * bufr - pointer to a global buffer. This is probably a kludge, - * but it was the nicest kludge I could think of (for now). - * bSize - The size of the global buffer <bufr>. - */ +#include "smb.h" +/* local variable pointing to passed filename */ +static char *pszParmFile = NULL; extern int DEBUGLEVEL; -static char *bufr = NULL; -static int bSize = 0; - -/* -------------------------------------------------------------------------- ** - * Functions... - */ - -static int EatWhitespace( FILE *InFile ) - /* ------------------------------------------------------------------------ ** - * Scan past whitespace (see ctype(3C)) and return the first non-whitespace - * character, or newline, or EOF. - * - * Input: InFile - Input source. - * - * Output: The next non-whitespace character in the input stream. - * - * Notes: Because the config files use a line-oriented grammar, we - * explicitly exclude the newline character from the list of - * whitespace characters. - * - Note that both EOF (-1) and the nul character ('\0') are - * considered end-of-file markers. - * - * ------------------------------------------------------------------------ ** - */ - { - int c; - - for( c = getc( InFile ); isspace( c ) && ('\n' != c); c = getc( InFile ) ) - ; - return( c ); - } /* EatWhitespace */ - -static int EatComment( FILE *InFile ) - /* ------------------------------------------------------------------------ ** - * Scan to the end of a comment. - * - * Input: InFile - Input source. - * - * Output: The character that marks the end of the comment. Normally, - * this will be a newline, but it *might* be an EOF. - * - * Notes: Because the config files use a line-oriented grammar, we - * explicitly exclude the newline character from the list of - * whitespace characters. - * - Note that both EOF (-1) and the nul character ('\0') are - * considered end-of-file markers. - * - * ------------------------------------------------------------------------ ** - */ - { - int c; - - for( c = getc( InFile ); ('\n'!=c) && (EOF!=c) && (c>0); c = getc( InFile ) ) - ; - return( c ); - } /* EatComment */ - -static int Continuation( char *line, int pos ) - /* ------------------------------------------------------------------------ ** - * Scan backards within a string to discover if the last non-whitespace - * character is a line-continuation character ('\\'). - * - * Input: line - A pointer to a buffer containing the string to be - * scanned. - * pos - This is taken to be the offset of the end of the - * string. This position is *not* scanned. - * - * Output: The offset of the '\\' character if it was found, or -1 to - * indicate that it was not. - * - * ------------------------------------------------------------------------ ** - */ - { - pos--; - while( (pos >= 0) && isspace(line[pos]) ) - pos--; - - return( ((pos >= 0) && ('\\' == line[pos])) ? pos : -1 ); - } /* Continuation */ - - -static BOOL Section( FILE *InFile, BOOL (*sfunc)(char *) ) - /* ------------------------------------------------------------------------ ** - * Scan a section name, and pass the name to function sfunc(). - * - * Input: InFile - Input source. - * sfunc - Pointer to the function to be called if the section - * name is successfully read. - * - * Output: True if the section name was read and True was returned from - * <sfunc>. False if <sfunc> failed or if a lexical error was - * encountered. - * - * ------------------------------------------------------------------------ ** - */ - { - int c; - int i; - int end; - char *func = "params.c:Section() -"; - - i = 0; /* <i> is the offset of the next free byte in bufr[] and */ - end = 0; /* <end> is the current "end of string" offset. In most */ - /* cases these will be the same, but if the last */ - /* character written to bufr[] is a space, then <end> */ - /* will be one less than <i>. */ - - c = EatWhitespace( InFile ); /* We've already got the '['. Scan */ - /* past initial white space. */ - - while( (EOF != c) && (c > 0) ) - { - - /* Check that the buffer is big enough for the next character. */ - if( i > (bSize - 2) ) - { - bSize += BUFR_INC; - bufr = Realloc( bufr, bSize ); - if( NULL == bufr ) - { - DEBUG(0, ("%s Memory re-allocation failure.", func) ); - return( False ); - } - } - /* Handle a single character. */ - switch( c ) +/************************************************************************** +Strip all leading whitespace from a string. +**************************************************************************/ +static void trimleft(char *psz) +{ + char *pszDest; + + pszDest = psz; + if (psz != NULL) + { + while (*psz != '\0' && isspace(*psz)) + psz++; + while (*psz != '\0') + *pszDest++ = *psz++; + *pszDest = '\0'; + } +} + +/************************************************************************** +Strip all trailing whitespace from a string. +**************************************************************************/ +static void trimright(char *psz) +{ + char *pszTemp; + + if (psz != NULL && psz[0] != '\0') + { + pszTemp = psz + strlen(psz) - 1; + while (isspace(*pszTemp)) + *pszTemp-- = '\0'; + } +} + +/*********************************************************************** +Collapse each whitespace area in a string to a single space. +***********************************************************************/ +static void collapse_spaces(char *psz) +{ + while (*psz) + if (isspace(*psz)) { - case ']': /* Found the closing bracket. */ - bufr[end] = '\0'; - if( 0 == end ) /* Don't allow an empty name. */ - { - DEBUG(0, ("%s Empty section name in configuration file.\n", func )); - return( False ); - } - if( !sfunc( bufr ) ) /* Got a valid name. Deal with it. */ - return( False ); - (void)EatComment( InFile ); /* Finish off the line. */ - return( True ); - - case '\n': /* Got newline before closing ']'. */ - i = Continuation( bufr, i ); /* Check for line continuation. */ - if( i < 0 ) - { - bufr[end] = '\0'; - DEBUG(0, ("%s Badly formed line in configuration file: %s\n", - func, bufr )); - return( False ); - } - end = ( (i > 0) && (' ' == bufr[i - 1]) ) ? (i - 1) : (i); - c = getc( InFile ); /* Continue with next line. */ - break; - - default: /* All else are a valid name chars. */ - if( isspace( c ) ) /* One space per whitespace region. */ - { - bufr[end] = ' '; - i = end + 1; - c = EatWhitespace( InFile ); - } - else /* All others copy verbatim. */ - { - bufr[i++] = c; - end = i; - c = getc( InFile ); - } + *psz++ = ' '; + trimleft(psz); } - } - - /* We arrive here if we've met the EOF before the closing bracket. */ - DEBUG(0, ("%s Unexpected EOF in the configuration file: %s\n", func, bufr )); - return( False ); - } /* Section */ - -static BOOL Parameter( FILE *InFile, BOOL (*pfunc)(char *, char *), int c ) - /* ------------------------------------------------------------------------ ** - * Scan a parameter name and value, and pass these two fields to pfunc(). - * - * Input: InFile - The input source. - * pfunc - A pointer to the function that will be called to - * process the parameter, once it has been scanned. - * c - The first character of the parameter name, which - * would have been read by Parse(). Unlike a comment - * line or a section header, there is no lead-in - * character that can be discarded. - * - * Output: True if the parameter name and value were scanned and processed - * successfully, else False. - * - * Notes: This function is in two parts. The first loop scans the - * parameter name. Internal whitespace is compressed, and an - * equal sign (=) terminates the token. Leading and trailing - * whitespace is discarded. The second loop scans the parameter - * value. When both have been successfully identified, they are - * passed to pfunc() for processing. - * - * ------------------------------------------------------------------------ ** - */ - { - int i = 0; /* Position within bufr. */ - int end = 0; /* bufr[end] is current end-of-string. */ - int vstart = 0; /* Starting position of the parameter value. */ - char *func = "params.c:Parameter() -"; - - /* Read the parameter name. */ - while( 0 == vstart ) /* Loop until we've found the start of the value. */ - { - - if( i > (bSize - 2) ) /* Ensure there's space for next char. */ + else + psz++; +} + +/************************************************************************** +Return the value of the first non-white character in the specified string. +The terminating NUL counts as non-white for the purposes of this function. +Note - no check for a NULL string! What would we return? +**************************************************************************/ +static int firstnonwhite(char *psz) +{ + while (isspace(*psz) && (*psz != '\0')) + psz++; + return (*psz); +} + + +/************************************************************************** +Identifies all parameters in the current section, calls the parameter +function for each. Ignores comment lines, stops and backs up in file when +a section is encountered. Returns True on success, False on error. +**************************************************************************/ +static BOOL enumerate_parameters(FILE *fileIn, BOOL (*pfunc)(char *,char *)) +{ + pstring szBuf; + char *pszTemp; + BOOL bRetval; + long lFileOffset; + int cTemp; + BOOL bParmFound; + + bRetval = False; + bParmFound = False; + while (True) + { + /* first remember where we are */ + if ((lFileOffset = ftell(fileIn)) >= 0L) { - bSize += BUFR_INC; - bufr = Realloc( bufr, bSize ); - if( NULL == bufr ) - { - DEBUG(0, ("%s Memory re-allocation failure.", func) ); - return( False ); - } + /* then get and check a line */ + if (fgets_slash(szBuf, sizeof(szBuf)-1, fileIn) == NULL) + { + /* stop - return OK unless file error */ + bRetval = !ferror(fileIn); + if (!bRetval) + DEBUG(0,( "Read error on configuration file (enumerating parameters)!\n")); + break; + } + else + /* if first non-white is a '[', stop (new section) */ + if ((cTemp = firstnonwhite(szBuf)) == '[') + { + /* restore position to start of new section */ + if (fseek(fileIn, lFileOffset, SEEK_SET) < 0L) + { + DEBUG(0,( "Seek error on configuration file!\n")); + break; + } + + /* return success */ + bRetval = True; + break; + } + else + /* if it's a semicolon or line is blank, ignore the line */ + if (!cTemp || strchr(";#",cTemp)) + { + continue; + } + else + /* if no equals sign and line contains non-whitespace */ + /* then line is badly formed */ + if ((pszTemp = strchr(szBuf, '=')) == NULL) + { + DEBUG(0,( "Ignoring badly formed line: %s", szBuf)); + } + else + { + /* Note that we have found a parameter */ + bParmFound = True; + /* cut line at the equals sign */ + *pszTemp++ = '\0'; + /* trim leading and trailing space from both halves */ + trimright(szBuf); + trimleft(szBuf); + trimright(pszTemp); + trimleft(pszTemp); + /* process the parameter iff passed pointer not NULL */ + if (pfunc != NULL) + if (!pfunc(szBuf, pszTemp)) + break; + } } - - switch( c ) - { - case '=': /* Equal sign marks end of param name. */ - if( 0 == end ) /* Don't allow an empty name. */ - { - DEBUG(0, ("%s Invalid parameter name in config. file.\n", func )); - return( False ); - } - bufr[end++] = '\0'; /* Mark end of string & advance. */ - i = end; /* New string starts here. */ - vstart = end; /* New string is parameter value. */ - bufr[i] = '\0'; /* New string is nul, for now. */ - break; - - case '\n': /* Find continuation char, else error. */ - i = Continuation( bufr, i ); - if( i < 0 ) - { - bufr[end] = '\0'; - DEBUG(1,("%s Ignoring badly formed line in configuration file: %s\n", - func, bufr )); - return( True ); - } - end = ( (i > 0) && (' ' == bufr[i - 1]) ) ? (i - 1) : (i); - c = getc( InFile ); /* Read past eoln. */ - break; - - case '\0': /* Shouldn't have EOF within param name. */ - case EOF: - bufr[i] = '\0'; - DEBUG(1,("%s Unexpected end-of-file at: %s\n", func, bufr )); - return( True ); - - default: - if( isspace( c ) ) /* One ' ' per whitespace region. */ - { - bufr[end] = ' '; - i = end + 1; - c = EatWhitespace( InFile ); - } - else /* All others verbatim. */ - { - bufr[i++] = c; - end = i; - c = getc( InFile ); - } - } - } - - /* Now parse the value. */ - c = EatWhitespace( InFile ); /* Again, trim leading whitespace. */ - while( (EOF !=c) && (c > 0) ) - { - - if( i > (bSize - 2) ) /* Make sure there's enough room. */ + } + return (bRetval); +} + + +/*********************************************************************** +Close up s by n chars, at offset start. +***********************************************************************/ +static void closestr(char *s, int start, int n) +{ + char *src; + char *dest; + int len; + + if (n > 0) + if ((src = dest = s) != NULL) { - bSize += BUFR_INC; - bufr = Realloc( bufr, bSize ); - if( NULL == bufr ) - { - DEBUG(0, ("%s Memory re-allocation failure.", func) ); - return( False ); - } + len = strlen(s); + if (start >= 0 && start < len - n) + { + src += start + n; + dest += start; + + while (*src) + *dest++ = *src++; + *dest = '\0'; + } } - - switch( c ) +} + +/************************************************************************** +Identifies all sections in the parameter file, calls passed section_func() +for each, passing the section name, then calls enumerate_parameters(). +Returns True on success, False on failure. Note that the section and +parameter names will have all internal whitespace areas collapsed to a +single space for processing. +**************************************************************************/ +static BOOL enumerate_sections(FILE *fileIn, + BOOL (*sfunc)(char *),BOOL (*pfunc)(char *,char *)) +{ + pstring szBuf; + BOOL bRetval; + BOOL bSectionFound; + + /* this makes sure we get include lines right */ + enumerate_parameters(fileIn, pfunc); + + bRetval = False; + bSectionFound = False; + while (True) + { + if (fgets_slash(szBuf, sizeof(szBuf)-1, fileIn) == NULL) { - case '\r': /* Explicitly remove '\r' because the older */ - c = getc( InFile ); /* version called fgets_slash() which also */ - break; /* removes them. */ - - case '\n': /* Marks end of value unless there's a '\'. */ - i = Continuation( bufr, i ); - if( i < 0 ) - c = 0; - else - { - for( end = i; (end >= 0) && isspace(bufr[end]); end-- ) - ; - c = getc( InFile ); - } - break; - - default: /* All others verbatim. Note that spaces do */ - bufr[i++] = c; /* not advance <end>. This allows trimming */ - if( !isspace( c ) ) /* of whitespace at the end of the line. */ - end = i; - c = getc( InFile ); - break; + /* stop - return OK unless file error */ + bRetval = !ferror(fileIn); + if (!bRetval) + DEBUG(0,( "Read error on configuration file (enumerating sections)!\n")); + break; } - } - bufr[end] = '\0'; /* End of value. */ - - return( pfunc( bufr, &bufr[vstart] ) ); /* Pass name & value to pfunc(). */ - } /* Parameter */ - -static BOOL Parse( FILE *InFile, - BOOL (*sfunc)(char *), - BOOL (*pfunc)(char *, char *) ) - /* ------------------------------------------------------------------------ ** - * Scan & parse the input. - * - * Input: InFile - Input source. - * sfunc - Function to be called when a section name is scanned. - * See Section(). - * pfunc - Function to be called when a parameter is scanned. - * See Parameter(). - * - * Output: True if the file was successfully scanned, else False. - * - * Notes: The input can be viewed in terms of 'lines'. There are four - * types of lines: - * Blank - May contain whitespace, otherwise empty. - * Comment - First non-whitespace character is a ';' or '#'. - * The remainder of the line is ignored. - * Section - First non-whitespace character is a '['. - * Parameter - The default case. - * - * ------------------------------------------------------------------------ ** - */ - { - int c; - char *func = "params.c:Parse() -"; - - c = EatWhitespace( InFile ); - while( (EOF != c) && (c > 0) ) - { - switch( c ) + else { - case '\n': /* Blank line. */ - c = EatWhitespace( InFile ); - break; - - case ';': /* Comment line. */ - case '#': - c = EatComment( InFile ); - break; - - case '[': /* Section Header. */ - if( !Section( InFile, sfunc ) ) - return( False ); - c = EatWhitespace( InFile ); - break; - - case '\\': /* Bogus backslash. */ - c = EatWhitespace( InFile ); - break; - - default: /* Parameter line. */ - if( !Parameter( InFile, pfunc, c ) ) - return( False ); - c = EatWhitespace( InFile ); - break; + trimleft(szBuf); + trimright(szBuf); + if (szBuf[0] == '[') + { + closestr(szBuf, 0, 1); + if (strlen(szBuf) > 1) + if (szBuf[strlen(szBuf) - 1] == ']') + { + /* found a section - note the fact */ + bSectionFound = True; + /* remove trailing metabracket */ + szBuf[strlen(szBuf) - 1] = '\0'; + /* remove leading and trailing whitespace from name */ + trimleft(szBuf); + trimright(szBuf); + /* reduce all internal whitespace to one space */ + collapse_spaces(szBuf); + /* process it - stop if the processing fails */ + if (sfunc != NULL) + if (!sfunc(szBuf)) + break; + if (!enumerate_parameters(fileIn, pfunc)) + break; + } + } } - } - return( True ); - } /* Parse */ - -static FILE *OpenConfFile( char *FileName ) - /* ------------------------------------------------------------------------ ** - * Open a configuration file. - * - * Input: FileName - The pathname of the config file to be opened. - * - * Output: A pointer of type (FILE *) to the opened file, or NULL if the - * file could not be opened. - * - * ------------------------------------------------------------------------ ** - */ - { - FILE *OpenedFile; - char *func = "params.c:OpenConfFile() -"; - - if( NULL == FileName || 0 == *FileName ) - { - DEBUG( 0, ("%s No configuration filename specified.\n", func) ); - return( NULL ); - } - - OpenedFile = fopen( FileName, "r" ); - if( NULL == OpenedFile ) - { - DEBUG( 0, - ("%s Unable to open configuration file \"%s\":\n\t%s\n", - func, FileName, strerror(errno)) ); - } - - return( OpenedFile ); - } /* OpenConfFile */ - -BOOL pm_process( char *FileName, - BOOL (*sfunc)(char *), - BOOL (*pfunc)(char *, char *) ) - /* ------------------------------------------------------------------------ ** - * Process the named parameter file. - * - * Input: FileName - The pathname of the parameter file to be opened. - * sfunc - A pointer to a function that will be called when - * a section name is discovered. - * pfunc - A pointer to a function that will be called when - * a parameter name and value are discovered. - * - * Output: TRUE if the file was successfully parsed, else FALSE. - * - * ------------------------------------------------------------------------ ** - */ - { - int result; - FILE *InFile; - char *func = "params.c:pm_process() -"; - - InFile = OpenConfFile( FileName ); /* Open the config file. */ - if( NULL == InFile ) - return( False ); - - DEBUG( 3, ("%s Processing configuration file \"%s\"\n", func, FileName) ); - - if( NULL != bufr ) /* If we already have a buffer */ - result = Parse( InFile, sfunc, pfunc ); /* (recursive call), then just */ - /* use it. */ - - else /* If we don't have a buffer */ - { /* allocate one, then parse, */ - bSize = BUFR_INC; /* then free. */ - bufr = (char *)malloc( bSize ); - if( NULL == bufr ) + } + + return (bRetval); +} + +/************************************************************************** +Process the passed parameter file. + +Returns True if successful, else False. +**************************************************************************/ +BOOL pm_process(char *pszFileName,BOOL (*sfunc)(char *),BOOL (*pfunc)(char *,char *)) +{ + FILE *fileIn; + BOOL bRetval; + + bRetval = False; + + /* record the filename for use in error messages one day... */ + pszParmFile = pszFileName; + + if (pszParmFile == NULL || strlen(pszParmFile) < 1) + DEBUG(0,( "No configuration filename specified!\n")); + else + if ((fileIn = fopen(pszParmFile, "r")) == NULL) + DEBUG(0,( "Unable to open configuration file \"%s\"!\n", pszParmFile)); + else { - DEBUG(0,("%s memory allocation failure.\n", func)); - return( False ); + DEBUG(3,("Processing configuration file \"%s\"\n", pszParmFile)); + bRetval = enumerate_sections(fileIn, sfunc, pfunc); + fclose(fileIn); } - result = Parse( InFile, sfunc, pfunc ); - free( bufr ); - bufr = NULL; - bSize = 0; - } - - if( !result ) /* Generic failure. */ - { - DEBUG(0,("%s Failed. Error returned from params.c:parse().\n", func)); - return( False ); - } - - return( True ); /* Generic success. */ - } /* pm_process */ - -/* -------------------------------------------------------------------------- */ + + if (!bRetval) + DEBUG(0,("pm_process retuned false\n")); + return (bRetval); +} + + diff --git a/source/passdb/smbpass.c b/source/passdb/smbpass.c index 441ab94ffbb..a31a10cef4b 100644 --- a/source/passdb/smbpass.c +++ b/source/passdb/smbpass.c @@ -1,3 +1,4 @@ +#ifdef SMB_PASSWD /* * Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup * Copyright (C) Andrew Tridgell 1992-1997 Modified by Jeremy Allison 1995. @@ -291,3 +292,8 @@ struct smb_passwd *get_smbpwnam(char *name) pw_file_unlock(lockfd); return NULL; } +#else + void smbpass_dummy(void) +{ +} /* To avoid compiler complaints */ +#endif diff --git a/source/script/installcp.sh b/source/script/installcp.sh deleted file mode 100755 index bafd84146d7..00000000000 --- a/source/script/installcp.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -LIBDIR=$1 -CODEPAGEDIR=$2 -BINDIR=$3 - -shift -shift -shift - -echo Installing codepage files in $CODEPAGEDIR -for d in $LIBDIR $CODEPAGEDIR; do -if [ ! -d $d ]; then -mkdir $d -if [ ! -d $d ]; then - echo Failed to make directory $d - exit 1 -fi -fi -done - -for p in $*; do - echo Creating codepage file $CODEPAGEDIR/codepage.$p from codepage_def.$p - $BINDIR/make_smbcodepage c $p codepage_def.$p $CODEPAGEDIR/codepage.$p -done - - -cat << EOF -====================================================================== -The code pages have been installed. You may uninstall them using the command -the command "make uninstallcp" or make "uninstall" to uninstall binaries, -man pages, shell scripts and code pages. -====================================================================== -EOF - -exit 0 - diff --git a/source/script/mkproto.awk b/source/script/mkproto.awk index 1ccf2fb2b0a..f2b76f20c97 100644 --- a/source/script/mkproto.awk +++ b/source/script/mkproto.awk @@ -64,7 +64,7 @@ BEGIN { next; } -!/^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types|arc4_key/ { +!/^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types/ { next; } diff --git a/source/script/uninstallcp.sh b/source/script/uninstallcp.sh deleted file mode 100755 index bd7013c358f..00000000000 --- a/source/script/uninstallcp.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/sh - -CPDIR=$1 -shift - -if [ ! -d $CPDIR ]; then - echo Directory $CPDIR does not exist! - echo Do a "make installcp" or "make install" first. - exit 1 -fi - -for p in $*; do - if [ ! -f $CPDIR/codepage.$p ]; then - echo $CPDIR/codepage.$p does not exist! - else - echo Removing $CPDIR/codepage.$p - rm -f $CPDIR/codepage.$p - if [ -f $CPDIR/codepage.$p ]; then - echo Cannot remove $CPDIR/codepage.$p... does $USER have privileges? - fi - fi -done - -cat << EOF -====================================================================== -The code pages have been uninstalled. You may reinstall them using -the command "make installcp" or "make install" to install binaries, -man pages, shell scripts and code pages. You may recover a previous version -(if any with "make revert"). -====================================================================== -EOF - -exit 0 diff --git a/source/smbd/dir.c b/source/smbd/dir.c index 316b58818fd..567bc14424e 100644 --- a/source/smbd/dir.c +++ b/source/smbd/dir.c @@ -470,12 +470,12 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo if (isrootdir && (strequal(filename,"..") || strequal(filename,"."))) continue; - pstrcpy(fname,filename); + strcpy(fname,filename); *path = 0; - pstrcpy(path,Connections[cnum].dirpath); + strcpy(path,Connections[cnum].dirpath); if(needslash) strcat(path,"/"); - pstrcpy(pathreal,path); + strcpy(pathreal,path); strcat(path,fname); strcat(pathreal,dname); if (sys_stat(pathreal,&sbuf) != 0) diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c index b9355c4ec07..1d7ee375d3f 100644 --- a/source/smbd/ipc.c +++ b/source/smbd/ipc.c @@ -440,7 +440,7 @@ static void PackDriverData(struct pack_desc* desc) } static int check_printq_info(struct pack_desc* desc, - int uLevel, char *id1, char *id2) + int uLevel, char *id1, const char* id2) { desc->subformat = NULL; switch( uLevel ) { @@ -1074,7 +1074,7 @@ static BOOL api_RNetServerEnum(int cnum, uint16 vuid, char *param, char *data, *rparam_len = 8; *rparam = REALLOC(*rparam,*rparam_len); - SSVAL(*rparam,0,NERR_Success); + SSVAL(*rparam,0,(missed == 0 ? NERR_Success : ERROR_MORE_DATA)); SSVAL(*rparam,2,0); SSVAL(*rparam,4,counted); SSVAL(*rparam,6,counted+missed); @@ -1601,13 +1601,14 @@ static BOOL api_PrintJobInfo(int cnum,uint16 vuid,char *param,char *data, name[l] = 0; DEBUG(3,("Setting print name to %s\n",name)); + + become_root(1); for (i=0;i<MAX_OPEN_FILES;i++) if (Files[i].open && Files[i].print_file) { pstring wd; GetWd(wd); - unbecome_user(); if (!become_user(Files[i].cnum,vuid) || !become_service(Files[i].cnum,True)) @@ -1617,6 +1618,8 @@ static BOOL api_PrintJobInfo(int cnum,uint16 vuid,char *param,char *data, string_set(&Files[i].name,name); break; } + + unbecome_root(1); } desc.errcode=NERR_Success; @@ -2219,7 +2222,6 @@ static BOOL api_WWkstaUserLogon(int cnum,uint16 vuid, char *param,char *data, int uLevel; struct pack_desc desc; char* name; - char* logon_script; uLevel = SVAL(p,0); name = p + 2; @@ -2262,14 +2264,7 @@ static BOOL api_WWkstaUserLogon(int cnum,uint16 vuid, char *param,char *data, PACKS(&desc,"z",mypath); /* computer */ } PACKS(&desc,"z",myworkgroup);/* domain */ - -/* JHT - By calling lp_logon_script() and standard_sub() we have */ -/* made sure all macros are fully substituted and available */ - logon_script = lp_logon_script(); - standard_sub( cnum, logon_script ); - PACKS(&desc,"z", logon_script); /* script path */ -/* End of JHT mods */ - + PACKS(&desc,"z",lp_logon_script()); /* script path */ PACKI(&desc,"D",0x00000000); /* reserved */ } diff --git a/source/smbd/mangle.c b/source/smbd/mangle.c index b0a45ffb47c..66e8233df28 100644 --- a/source/smbd/mangle.c +++ b/source/smbd/mangle.c @@ -123,34 +123,30 @@ BOOL is_8_3(char *fname, BOOL check_case) { char *p = fname; - if(lp_client_code_page() == KANJI_CODEPAGE) - { - dot_pos = 0; - while (*p) +#ifdef KANJI + dot_pos = 0; + while (*p) { - if (is_shift_jis (*p)) - p += 2; - else if (is_kana (*p)) - p ++; - else - { - if (*p == '.' && !dot_pos) - dot_pos = (char *) p; - if (!isdoschar(*p)) - return(False); - p++; - } - } - } - else - { - while (*p) + if (is_shift_jis (*p)) { + p += 2; + } else if (is_kana (*p)) { + p ++; + } else { + if (*p == '.' && !dot_pos) + dot_pos = (char *) p; + if (!isdoschar(*p)) + return(False); + p++; + } + } +#else + while (*p) { - if (!isdoschar(*p)) - return(False); - p++; + if (!isdoschar(*p)) + return(False); + p++; } - } +#endif /* KANJI */ } /* no dot and less than 9 means OK */ @@ -502,90 +498,84 @@ void mangle_name_83(char *s) DEBUG(5,("Mangling name %s to ",s)); if (p) - { - if (p == s) - strcpy(extension,"___"); - else + { + if (p == s) + strcpy(extension,"___"); + else { *p++ = 0; while (*p && extlen < 3) - { - if(lp_client_code_page() == KANJI_CODEPAGE) - { - if (is_shift_jis (*p)) - { - if (extlen < 2) - { - extension[extlen++] = p[0]; - extension[extlen++] = p[1]; - } - else - { - extension[extlen++] = base36 (((unsigned char) *p) % 36); - } - p += 2; - } - else if (is_kana (*p)) - { - extension[extlen++] = p[0]; - p++; - } - else - { - if (isdoschar (*p) && *p != '.') - extension[extlen++] = p[0]; - p++; - } - } - else - { - if (isdoschar(*p) && *p != '.') - extension[extlen++] = *p; - p++; - } - } + { +#ifdef KANJI + if (is_shift_jis (*p)) + { + if (extlen < 2) + { + extension[extlen++] = p[0]; + extension[extlen++] = p[1]; + } + else + { + extension[extlen++] = base36 (((unsigned char) *p) % 36); + } + p += 2; + } + else if (is_kana (*p)) + { + extension[extlen++] = p[0]; + p++; + } + else + { + if (isdoschar (*p) && *p != '.') + extension[extlen++] = p[0]; + p++; + } +#else + if (isdoschar(*p) && *p != '.') + extension[extlen++] = *p; + p++; +#endif /* KANJI */ + } extension[extlen] = 0; + } } - } p = s; while (*p && baselen < 5) - { - if(lp_client_code_page() == KANJI_CODEPAGE) { +#ifdef KANJI if (is_shift_jis (*p)) - { - if (baselen < 4) - { - base[baselen++] = p[0]; - base[baselen++] = p[1]; - } - else - { + { + if (baselen < 4) + { + base[baselen++] = p[0]; + base[baselen++] = p[1]; + } + else + { base[baselen++] = base36 (((unsigned char) *p) % 36); - } - p += 2; - } + } + p += 2; + } else if (is_kana (*p)) - { - base[baselen++] = p[0]; - p++; - } + { + base[baselen++] = p[0]; + p++; + } else - { - if (isdoschar (*p) && *p != '.') - base[baselen++] = p[0]; - p++; - } - } - else - { + { + if (isdoschar (*p) && *p != '.') + base[baselen++] = p[0]; + p++; + } +#else if (isdoschar(*p) && *p != '.') - base[baselen++] = *p; + base[baselen++] = *p; p++; +#endif /* KANJI */ } - } base[baselen] = 0; csum = csum % (36*36); @@ -611,9 +601,8 @@ static BOOL illegal_name(char *name) static BOOL initialised=False; unsigned char *s; - if (!initialised) - { - char *ill = "*\\/?<>|\":{}"; + if (!initialised) { + char *ill = "*\\/?<>|\":"; initialised = True; bzero((char *)illegal,256); @@ -621,23 +610,21 @@ static BOOL illegal_name(char *name) illegal[*s] = True; } - if(lp_client_code_page() == KANJI_CODEPAGE) - { - for (s = (unsigned char *)name; *s;) { - if (is_shift_jis (*s)) { - s += 2; - } else if (illegal[*s]) { - return(True); - } else { - s++; - } +#ifdef KANJI + for (s = (unsigned char *)name; *s;) { + if (is_shift_jis (*s)) { + s += 2; + } else if (illegal[*s]) { + return(True); + } else { + s++; } } - else - { - for (s = (unsigned char *)name;*s;s++) - if (illegal[*s]) return(True); - } +#else + for (s = (unsigned char *)name;*s;s++) + if (illegal[*s]) return(True); +#endif + return(False); } diff --git a/source/smbd/password.c b/source/smbd/password.c index f4d94791cf3..6d84a5ff61c 100644 --- a/source/smbd/password.c +++ b/source/smbd/password.c @@ -36,6 +36,7 @@ static char this_user[100]=""; static char this_salt[100]=""; static char this_crypted[100]=""; +#ifdef SMB_PASSWD /* Data to do lanman1/2 password challenge. */ static unsigned char saved_challenge[8]; static BOOL challenge_sent=False; @@ -45,24 +46,17 @@ Get the next challenge value - no repeats. ********************************************************************/ void generate_next_challenge(char *challenge) { - unsigned char buf[16]; - static int counter = 0; - struct timeval tval; - int v1,v2; - - /* get a sort-of random number */ - GetTimeOfDay(&tval); - v1 = (counter++) + getpid() + tval.tv_sec; - v2 = (counter++) * getpid() + tval.tv_usec; - SIVAL(challenge,0,v1); - SIVAL(challenge,4,v2); - - /* mash it up with md4 */ - mdfour(buf, (unsigned char *)challenge, 8); - - memcpy(saved_challenge, buf, 8); - memcpy(challenge,buf,8); - challenge_sent = True; + static int counter = 0; + struct timeval tval; + int v1,v2; + GetTimeOfDay(&tval); + v1 = (counter++) + getpid() + tval.tv_sec; + v2 = (counter++) * getpid() + tval.tv_usec; + SIVAL(challenge,0,v1); + SIVAL(challenge,4,v2); + E1((uchar *)challenge,(uchar *)"SAMBA",(uchar *)saved_challenge); + memcpy(challenge,saved_challenge,8); + challenge_sent = True; } /******************************************************************* @@ -84,6 +78,7 @@ BOOL last_challenge(char *challenge) memcpy(challenge,saved_challenge,8); return(True); } +#endif /* this holds info on user ids that are already validated for this VC */ static user_struct *validated_users = NULL; @@ -406,7 +401,7 @@ static char *PAM_password; * echo off means password. */ static int PAM_conv (int num_msg, - struct pam_message **msg, + const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { int count = 0, replies = 0; @@ -817,6 +812,7 @@ Hence we make a direct return to avoid a second chance!!! #endif } +#ifdef SMB_PASSWD /**************************************************************************** core of smb password checking routine. ****************************************************************************/ @@ -858,6 +854,7 @@ BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned cha #endif return (memcmp(p24, password, 24) == 0); } +#endif /**************************************************************************** check if a username/password is OK @@ -867,16 +864,21 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) pstring pass2; int level = lp_passwordlevel(); struct passwd *pass; +#ifdef SMB_PASSWD char challenge[8]; struct smb_passwd *smb_pass; BOOL challenge_done = False; +#endif if (password) password[pwlen] = 0; +#ifdef SMB_PASSWD if (pwlen == 24) challenge_done = last_challenge(challenge); +#endif #if DEBUG_PASSWORD +#ifdef SMB_PASSWD if (challenge_done) { int i; @@ -884,9 +886,10 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) for( i = 0; i < 24; i++) DEBUG(100,("%0x ", (unsigned char)password[i])); DEBUG(100,("]\n")); - } else { - DEBUG(100,("checking user=[%s] pass=[%s]\n",user,password)); } + else +#endif + DEBUG(100,("checking user=[%s] pass=[%s]\n",user,password)); #endif if (!password) @@ -903,6 +906,8 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) else pass = Get_Pwnam(user,True); +#ifdef SMB_PASSWD + DEBUG(4,("SMB Password - pwlen = %d, challenge_done = %d\n", pwlen, challenge_done)); if((pwlen == 24) && challenge_done) @@ -959,6 +964,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) DEBUG(3,("Error smb_password_check failed\n")); } +#endif DEBUG(4,("Checking password for user %s (l=%d)\n",user,pwlen)); @@ -1520,7 +1526,7 @@ BOOL server_cryptkey(char *buf) struct in_addr dest_ip; int port = SMB_PORT; BOOL ret; - + if(secserver_inbuf == NULL) { secserver_inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); if(secserver_inbuf == NULL) { @@ -1590,12 +1596,12 @@ BOOL server_cryptkey(char *buf) and the remote machine name. */ { - char buf2[32]; /* create name as PIDname */ - sprintf(buf2,"%d", getpid()); - strncpy(&buf2[strlen(buf2)], remote_machine, 31 - strlen(buf2)); - buf2[31] = '\0'; - DEBUG(1,("negprot w/password server as %s\n",buf2)); - name_mangle(buf2,p,' '); + char buf[32]; /* create name as PIDname */ + sprintf(buf,"%d", getpid()); + strncpy(&buf[strlen(buf)], remote_machine, 31 - strlen(buf)); + buf[31] = '\0'; + DEBUG(1,("negprot w/password server as %s\n",buf)); + name_mangle(buf,p,' '); len += name_len(p); } diff --git a/source/smbd/pipes.c b/source/smbd/pipes.c index a465e911459..2cc6eea506f 100644 --- a/source/smbd/pipes.c +++ b/source/smbd/pipes.c @@ -127,7 +127,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) unixmode = unix_mode(cnum,smb_attr); open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode, - 0, &rmode,&smb_action); + &rmode,&smb_action); if (!Files[fnum].open) { @@ -141,7 +141,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) } if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) { - close_file(fnum); + close_file(fnum, 0); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -149,7 +149,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) fmode = dos_mode(cnum,fname,&sbuf); mtime = sbuf.st_mtime; if (fmode & aDIR) { - close_file(fnum); + close_file(fnum, 0); return(ERROR(ERRDOS,ERRnoaccess)); } diff --git a/source/smbd/predict.c b/source/smbd/predict.c index 691d8fbb4e0..7d6b2498f5a 100644 --- a/source/smbd/predict.c +++ b/source/smbd/predict.c @@ -53,24 +53,37 @@ int read_predict(int fd,int offset,char *buf,char **ptr,int num) offset >= rp_offset && possible>0 && smb_last_time-rp_time < rp_timeout) - { - ret = possible; - if (buf) - memcpy(buf,rp_buffer + (offset-rp_offset),possible); - else - *ptr = rp_buffer + (offset-rp_offset); - DEBUG(5,("read-prediction gave %d bytes of %d\n",ret,num)); - } + { + ret = possible; + if (buf) + memcpy(buf,rp_buffer + (offset-rp_offset),possible); + else + *ptr = rp_buffer + (offset-rp_offset); + DEBUG(5,("read-prediction gave %d bytes of %d\n",ret,num)); + } if (ret == num) { predict_skip = True; } else { - predict_skip = False; + struct stat rp_stat; + + /* Find the end of the file - ensure we don't + read predict beyond it. */ + if(fstat(fd,&rp_stat) < 0) + { + DEBUG(0,("read-prediction failed on fstat. Error was %s\n", strerror(errno))); + predict_skip = True; + } + else + { + predict_skip = False; - /* prepare the next prediction */ - rp_predict_fd = fd; - rp_predict_offset = offset + num; - rp_predict_length = num; + /* prepare the next prediction */ + rp_predict_fd = fd; + /* Make sure we don't seek beyond the end of the file. */ + rp_predict_offset = MIN((offset + num),rp_stat.st_size); + rp_predict_length = num; + } } if (ret < 0) ret = 0; diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c index d4f746c9e36..2d238dfaf17 100644 --- a/source/smbd/quotas.c +++ b/source/smbd/quotas.c @@ -416,10 +416,12 @@ BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize) } return (True); } + #else #ifdef __FreeBSD__ #include <ufs/ufs/quota.h> +#include <machine/param.h> #elif AIX /* AIX quota patch from Ole Holm Nielsen <ohnielse@fysik.dtu.dk> */ #include <jfs/quota.h> @@ -463,7 +465,25 @@ BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize) } #else /* USE_SETRES */ #if defined(__FreeBSD__) - r= quotactl(path,Q_GETQUOTA,euser_id,(char *) &D); + { + /* FreeBSD patches from Marty Moll <martym@arbor.edu> */ + uid_t user_id; + gid_t egrp_id; + + /* Need to be root to get quotas in FreeBSD */ + user_id = getuid(); + egrp_id = getegid(); + setuid(0); + seteuid(0); + r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D); + + /* As FreeBSD has group quotas, if getting the user + quota fails, try getting the group instead. */ + if (r) + r= quotactl(path,QCMD(Q_GETQUOTA,GRPQUOTA),egrp_id,(char *) &D); + setuid(user_id); + seteuid(euser_id); + } #elif defined(AIX) /* AIX has both USER and GROUP quotas: Get the USER quota (ohnielse@fysik.dtu.dk) */ @@ -474,7 +494,12 @@ BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize) #endif /* USE_SETRES */ /* Use softlimit to determine disk space, except when it has been exceeded */ +#if defined(__FreeBSD__) + *bsize = DEV_BSIZE; +#else /* !__FreeBSD__ */ *bsize = 1024; +#endif /*!__FreeBSD__ */ + if (r) { if (errno == EDQUOT) diff --git a/source/smbd/reply.c b/source/smbd/reply.c index a8f674183c5..ffa80aac870 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -42,7 +42,6 @@ extern BOOL short_case_preserve; extern pstring sesssetup_user; extern fstring myworkgroup; extern int Client; -extern int global_oplock_break; /* this macro should always be used to extract an fnum (smb_fid) from a packet to ensure chaining works correctly */ @@ -66,18 +65,18 @@ static void overflow_attack(int len) ****************************************************************************/ int reply_special(char *inbuf,char *outbuf) { - int outsize = 4; - int msg_type = CVAL(inbuf,0); - int msg_flags = CVAL(inbuf,1); - pstring name1,name2; - extern fstring remote_machine; - extern fstring local_machine; - char *p; - - *name1 = *name2 = 0; - - smb_setlen(outbuf,0); - + int outsize = 4; + int msg_type = CVAL(inbuf,0); + int msg_flags = CVAL(inbuf,1); + pstring name1,name2; + extern fstring remote_machine; + extern fstring local_machine; + char *p; + + *name1 = *name2 = 0; + + smb_setlen(outbuf,0); + switch (msg_type) { case 0x81: /* session request */ CVAL(outbuf,0) = 0x82; @@ -122,15 +121,15 @@ int reply_special(char *inbuf,char *outbuf) DEBUG(0,("Unexpected session response\n")); break; - case 0x85: /* session keepalive */ - default: - return(0); - } - + case 0x85: /* session keepalive */ + default: + return(0); + } + DEBUG(5,("%s init msg_type=0x%x msg_flags=0x%x\n", timestring(),msg_type,msg_flags)); - - return(outsize); + + return(outsize); } @@ -252,7 +251,7 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize) if ((SVAL(inbuf,smb_vwv2) & 0x1) != 0) close_cnum(SVAL(inbuf,smb_tid),vuid); - if (passlen > MAX_PASSWORD_LENGTH) { + if (passlen > MAX_PASS_LEN) { overflow_attack(passlen); } @@ -388,7 +387,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (Protocol < PROTOCOL_NT1) { smb_apasslen = SVAL(inbuf,smb_vwv7); - if (smb_apasslen > MAX_PASSWORD_LENGTH) + if (smb_apasslen > MAX_PASS_LEN) { overflow_attack(smb_apasslen); } @@ -423,12 +422,12 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (passlen1 != 24 && passlen2 != 24) doencrypt = False; - if (passlen1 > MAX_PASSWORD_LENGTH) { + if (passlen1 > MAX_PASS_LEN) { overflow_attack(passlen1); } - passlen1 = MIN(passlen1, MAX_PASSWORD_LENGTH); - passlen2 = MIN(passlen2, MAX_PASSWORD_LENGTH); + passlen1 = MIN(passlen1, MAX_PASS_LEN); + passlen2 = MIN(passlen2, MAX_PASS_LEN); if(doencrypt) { /* Save the lanman2 password and the NT md4 password. */ @@ -599,7 +598,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (!done_sesssetup) max_send = MIN(max_send,smb_bufsize); - DEBUG(6,("Client requested max send size of %d\n", max_send)); + DEBUG(5,(" Client requested max send size of %d\n", max_send)); done_sesssetup = True; @@ -640,15 +639,6 @@ int reply_chkpth(char *inbuf,char *outbuf) unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadpath; } - - /* Ugly - NT specific hack - but needed (JRA) */ - if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) && - (get_remote_arch() == RA_WINNT)) - { - unix_ERR_class = ERRDOS; - unix_ERR_code = ERRbaddirectory; - } - return(UNIXERROR(ERRDOS,ERRbadpath)); } @@ -1111,8 +1101,6 @@ int reply_open(char *inbuf,char *outbuf) int rmode=0; struct stat sbuf; BOOL bad_path = False; - files_struct *fsp; - int oplock_request = CORE_OPLOCK_REQUEST(inbuf); cnum = SVAL(inbuf,smb_tid); @@ -1137,12 +1125,9 @@ int reply_open(char *inbuf,char *outbuf) unixmode = unix_mode(cnum,aARCH); - open_file_shared(fnum,cnum,fname,share_mode,3,unixmode, - oplock_request,&rmode,NULL); - - fsp = &Files[fnum]; + open_file_shared(fnum,cnum,fname,share_mode,3,unixmode,&rmode,NULL); - if (!fsp->open) + if (!Files[fnum].open) { if((errno == ENOENT) && bad_path) { @@ -1152,8 +1137,8 @@ int reply_open(char *inbuf,char *outbuf) return(UNIXERROR(ERRDOS,ERRnoaccess)); } - if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) { - close_file(fnum); + if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) { + close_file(fnum, 0); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -1163,7 +1148,7 @@ int reply_open(char *inbuf,char *outbuf) if (fmode & aDIR) { DEBUG(3,("attempt to open a directory %s\n",fname)); - close_file(fnum); + close_file(fnum, 0); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -1174,12 +1159,10 @@ int reply_open(char *inbuf,char *outbuf) SIVAL(outbuf,smb_vwv4,size); SSVAL(outbuf,smb_vwv6,rmode); - if (oplock_request && lp_fake_oplocks(SNUM(cnum))) { - CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; + if (lp_fake_oplocks(SNUM(cnum))) { + CVAL(outbuf,smb_flg) |= (CVAL(inbuf,smb_flg) & (1<<5)); } - if(fsp->granted_oplock) - CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; return(outsize); } @@ -1194,7 +1177,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) int fnum = -1; int smb_mode = SVAL(inbuf,smb_vwv3); int smb_attr = SVAL(inbuf,smb_vwv5); - BOOL oplock_request = EXTENDED_OPLOCK_REQUEST(inbuf); + BOOL oplock_request = BITSETW(inbuf+smb_vwv2,1); #if 0 int open_flags = SVAL(inbuf,smb_vwv2); int smb_sattr = SVAL(inbuf,smb_vwv4); @@ -1206,7 +1189,6 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) struct stat sbuf; int smb_action = 0; BOOL bad_path = False; - files_struct *fsp; /* If it's an IPC, pass off the pipe handler. */ if (IS_IPC(cnum)) @@ -1234,11 +1216,9 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) unixmode = unix_mode(cnum,smb_attr | aARCH); open_file_shared(fnum,cnum,fname,smb_mode,smb_ofun,unixmode, - oplock_request, &rmode,&smb_action); + &rmode,&smb_action); - fsp = &Files[fnum]; - - if (!fsp->open) + if (!Files[fnum].open) { if((errno == ENOENT) && bad_path) { @@ -1248,8 +1228,8 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) return(UNIXERROR(ERRDOS,ERRnoaccess)); } - if (fstat(fsp->fd_ptr->fd,&sbuf) != 0) { - close_file(fnum); + if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) { + close_file(fnum, 0); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -1257,18 +1237,12 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) fmode = dos_mode(cnum,fname,&sbuf); mtime = sbuf.st_mtime; if (fmode & aDIR) { - close_file(fnum); + close_file(fnum, 0); return(ERROR(ERRDOS,ERRnoaccess)); } if (oplock_request && lp_fake_oplocks(SNUM(cnum))) { - smb_action |= EXTENDED_OPLOCK_GRANTED; - CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; - } - - if(fsp->granted_oplock) { - smb_action |= EXTENDED_OPLOCK_GRANTED; - CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; + smb_action |= (1<<15); } set_message(outbuf,15,0,True); @@ -1303,7 +1277,7 @@ int reply_ulogoffX(char *inbuf,char *outbuf,int length,int bufsize) int i; for (i=0;i<MAX_OPEN_FILES;i++) if (Files[i].uid == vuser->uid && Files[i].open) { - close_file(i); + close_file(i, 0); } } @@ -1330,8 +1304,6 @@ int reply_mknew(char *inbuf,char *outbuf) mode_t unixmode; int ofun = 0; BOOL bad_path = False; - files_struct *fsp; - int oplock_request = CORE_OPLOCK_REQUEST(inbuf); com = SVAL(inbuf,smb_com); cnum = SVAL(inbuf,smb_tid); @@ -1373,12 +1345,9 @@ int reply_mknew(char *inbuf,char *outbuf) } /* Open file in dos compatibility share mode. */ - open_file_shared(fnum,cnum,fname,(DENY_FCB<<4)|0xF, ofun, unixmode, - oplock_request, NULL, NULL); + open_file_shared(fnum,cnum,fname,(DENY_FCB<<4)|0xF, ofun, unixmode, NULL, NULL); - fsp = &Files[fnum]; - - if (!fsp->open) + if (!Files[fnum].open) { if((errno == ENOENT) && bad_path) { @@ -1391,13 +1360,10 @@ int reply_mknew(char *inbuf,char *outbuf) outsize = set_message(outbuf,1,0,True); SSVAL(outbuf,smb_vwv0,fnum); - if (oplock_request && lp_fake_oplocks(SNUM(cnum))) { - CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; + if (lp_fake_oplocks(SNUM(cnum))) { + CVAL(outbuf,smb_flg) |= (CVAL(inbuf,smb_flg) & (1<<5)); } - - if(fsp->granted_oplock) - CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; - + DEBUG(2,("new file %s\n",fname)); DEBUG(3,("%s mknew %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n",timestring(),fname,Files[fnum].fd_ptr->fd,fnum,cnum,createmode,unixmode)); @@ -1418,8 +1384,6 @@ int reply_ctemp(char *inbuf,char *outbuf) int createmode; mode_t unixmode; BOOL bad_path = False; - files_struct *fsp; - int oplock_request = CORE_OPLOCK_REQUEST(inbuf); cnum = SVAL(inbuf,smb_tid); createmode = SVAL(inbuf,smb_vwv0); @@ -1447,12 +1411,9 @@ int reply_ctemp(char *inbuf,char *outbuf) /* Open file in dos compatibility share mode. */ /* We should fail if file exists. */ - open_file_shared(fnum,cnum,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode, - oplock_request, NULL, NULL); + open_file_shared(fnum,cnum,fname2,(DENY_FCB<<4)|0xF, 0x10, unixmode, NULL, NULL); - fsp = &Files[fnum]; - - if (!fsp->open) + if (!Files[fnum].open) { if((errno == ENOENT) && bad_path) { @@ -1467,13 +1428,10 @@ int reply_ctemp(char *inbuf,char *outbuf) CVAL(smb_buf(outbuf),0) = 4; strcpy(smb_buf(outbuf) + 1,fname2); - if (oplock_request && lp_fake_oplocks(SNUM(cnum))) { - CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; + if (lp_fake_oplocks(SNUM(cnum))) { + CVAL(outbuf,smb_flg) |= (CVAL(inbuf,smb_flg) & (1<<5)); } - if(fsp->granted_oplock) - CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED; - DEBUG(2,("created temp file %s\n",fname2)); DEBUG(3,("%s ctemp %s fd=%d fnum=%d cnum=%d dmode=%d umode=%o\n",timestring(),fname2,Files[fnum].fd_ptr->fd,fnum,cnum,createmode,unixmode)); @@ -1621,22 +1579,6 @@ int reply_readbraw(char *inbuf, char *outbuf) int fd; char *fname; -#ifdef USE_OPLOCKS - /* - * Special check if an oplock break has been issued - * and the readraw request croses on the wire, we must - * return a zero length response here. - */ - - if(global_oplock_break) - { - _smb_setlen(header,0); - transfer_file(0,Client,0,header,4,0); - DEBUG(5,("readbraw - oplock break finished\n")); - return -1; - } -#endif - cnum = SVAL(inbuf,smb_tid); fnum = GETFNUM(inbuf,smb_vwv0); @@ -2248,7 +2190,7 @@ int reply_close(char *inbuf,char *outbuf) /* try and set the date */ set_filetime(Files[fnum].name,mtime); - close_file(fnum); + close_file(fnum, 1); /* We have a cached error */ if(eclass || err) @@ -2295,7 +2237,7 @@ int reply_writeclose(char *inbuf,char *outbuf) set_filetime(Files[fnum].name,mtime); - close_file(fnum); + close_file(fnum, 1); DEBUG(3,("%s writeclose fnum=%d cnum=%d num=%d wrote=%d (numopen=%d)\n", timestring(),fnum,cnum,numtowrite,nwritten, @@ -2492,8 +2434,7 @@ int reply_printopen(char *inbuf,char *outbuf) return(ERROR(ERRDOS,ERRnoaccess)); /* Open for exclusive use, write only. */ - open_file_shared(fnum,cnum,fname2,(DENY_ALL<<4)|1, 0x12, unix_mode(cnum,0), - 0, NULL, NULL); + open_file_shared(fnum,cnum,fname2,(DENY_ALL<<4)|1, 0x12, unix_mode(cnum,0), NULL, NULL); if (!Files[fnum].open) return(UNIXERROR(ERRDOS,ERRnoaccess)); @@ -2527,7 +2468,7 @@ int reply_printclose(char *inbuf,char *outbuf) if (!CAN_PRINT(cnum)) return(ERROR(ERRDOS,ERRnoaccess)); - close_file(fnum); + close_file(fnum, 1); DEBUG(3,("%s printclose fd=%d fnum=%d cnum=%d\n",timestring(),Files[fnum].fd_ptr->fd,fnum,cnum)); @@ -2695,66 +2636,6 @@ int reply_mkdir(char *inbuf,char *outbuf) return(outsize); } -/**************************************************************************** -Static function used by reply_rmdir to delete an entire directory -tree recursively. -****************************************************************************/ -static BOOL recursive_rmdir(char *directory) -{ - char *dname = NULL; - BOOL ret = False; - void *dirptr = OpenDir(-1, directory, False); - - if(dirptr == NULL) - return True; - - while((dname = ReadDirName(dirptr))) - { - pstring fullname; - struct stat st; - - if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) - continue; - - /* Construct the full name. */ - if(strlen(directory) + strlen(dname) + 1 >= sizeof(fullname)) - { - errno = ENOMEM; - ret = True; - break; - } - strcpy(fullname, directory); - strcat(fullname, "/"); - strcat(fullname, dname); - - if(sys_lstat(fullname, &st) != 0) - { - ret = True; - break; - } - - if(st.st_mode & S_IFDIR) - { - if(recursive_rmdir(fullname)!=0) - { - ret = True; - break; - } - if(sys_rmdir(fullname) != 0) - { - ret = True; - break; - } - } - else if(sys_unlink(fullname) != 0) - { - ret = True; - break; - } - } - CloseDir(dirptr); - return ret; -} /**************************************************************************** reply to a rmdir @@ -2823,15 +2704,10 @@ int reply_rmdir(char *inbuf,char *outbuf) if(sys_lstat(fullname, &st) != 0) break; if(st.st_mode & S_IFDIR) - { - if(lp_recursive_veto_delete(SNUM(cnum))) { - if(recursive_rmdir(fullname) != 0) + if(sys_rmdir(fullname) != 0) break; } - if(sys_rmdir(fullname) != 0) - break; - } else if(sys_unlink(fullname) != 0) break; } @@ -3155,7 +3031,7 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun, fnum1 = find_free_file(); if (fnum1<0) return(False); open_file_shared(fnum1,cnum,src,(DENY_NONE<<4), - 1,0,0,&Access,&action); + 1,0,&Access,&action); if (!Files[fnum1].open) return(False); @@ -3164,14 +3040,14 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun, fnum2 = find_free_file(); if (fnum2<0) { - close_file(fnum1); + close_file(fnum1, 0); return(False); } open_file_shared(fnum2,cnum,dest,(DENY_NONE<<4)|1, - ofun,st.st_mode,0,&Access,&action); + ofun,st.st_mode,&Access,&action); if (!Files[fnum2].open) { - close_file(fnum1); + close_file(fnum1, 0); return(False); } @@ -3182,8 +3058,8 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun, if (st.st_size) ret = transfer_file(Files[fnum1].fd_ptr->fd,Files[fnum2].fd_ptr->fd,st.st_size,NULL,0,0); - close_file(fnum1); - close_file(fnum2); + close_file(fnum1, 0); + close_file(fnum2, 0); return(ret == st.st_size); } @@ -3370,10 +3246,7 @@ int reply_setdir(char *inbuf,char *outbuf) int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize) { int fnum = GETFNUM(inbuf,smb_vwv2); - unsigned char locktype = CVAL(inbuf,smb_vwv3); -#if 0 - unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1); -#endif /* USE_OPLOCKS */ + uint16 locktype = SVAL(inbuf,smb_vwv3); uint16 num_ulocks = SVAL(inbuf,smb_vwv6); uint16 num_locks = SVAL(inbuf,smb_vwv7); uint32 count, offset; @@ -3390,50 +3263,6 @@ int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize) CHECK_ERROR(fnum); data = smb_buf(inbuf); - -#ifdef USE_OPLOCKS - /* Check if this is an oplock break on a file - we have granted an oplock on. - */ - if((locktype == LOCKING_ANDX_OPLOCK_RELEASE) && - (num_ulocks == 0) && (num_locks == 0) && - (CVAL(inbuf,smb_vwv0) == 0xFF)) - { - share_lock_token token; - files_struct *fsp = &Files[fnum]; - uint32 dev = fsp->fd_ptr->dev; - uint32 inode = fsp->fd_ptr->inode; - - DEBUG(5,("reply_lockingX: oplock break reply from client for fnum = %d\n", - fnum)); - /* - * Make sure we have granted an oplock on this file. - */ - if(!fsp->granted_oplock) - { - DEBUG(0,("reply_lockingX: Error : oplock break from client for fnum = %d and \ -no oplock granted on this file.\n", fnum)); - return ERROR(ERRDOS,ERRlock); - } - - /* Remove the oplock flag from the sharemode. */ - lock_share_entry(fsp->cnum, dev, inode, &token); - if(remove_share_oplock( fnum, token)==False) - { - DEBUG(0,("reply_lockingX: failed to remove share oplock for fnum %d, \ -dev = %x, inode = %x\n", fnum, dev, inode)); - unlock_share_entry(fsp->cnum, dev, inode, token); - return -1; - } - unlock_share_entry(fsp->cnum, dev, inode, token); - - /* Clear the granted flag and return. */ - - fsp->granted_oplock = False; - return -1; - } -#endif /* USE_OPLOCKS */ - /* Data now points at the beginning of the list of smb_unlkrng structs */ for(i = 0; i < (int)num_ulocks; i++) { @@ -3468,7 +3297,7 @@ dev = %x, inode = %x\n", fnum, dev, inode)); set_message(outbuf,2,0,True); DEBUG(3,("%s lockingX fnum=%d cnum=%d type=%d num_locks=%d num_ulocks=%d\n", - timestring(),fnum,cnum,(unsigned int)locktype,num_locks,num_ulocks)); + timestring(),fnum,cnum,locktype,num_locks,num_ulocks)); chain_fnum = fnum; @@ -3821,3 +3650,8 @@ int reply_getattrE(char *inbuf,char *outbuf) return(outsize); } + + + + + diff --git a/source/smbd/server.c b/source/smbd/server.c index b250572a1f4..3bfd5bbbf40 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -84,16 +84,6 @@ int chain_fnum = -1; /* number of open connections */ static int num_connections_open = 0; -#ifdef USE_OPLOCKS -/* Oplock ipc UDP socket. */ -int oplock_sock = -1; -uint16 oplock_port = 0; -/* Current number of oplocks we have outstanding. */ -int32 global_oplocks_open = 0; -#endif /* USE_OPLOCKS */ - -BOOL global_oplock_break = False; - extern fstring remote_machine; pstring OriginalDir; @@ -189,7 +179,7 @@ int dos_mode(int cnum,char *path,struct stat *sbuf) int result = 0; extern struct current_user current_user; - DEBUG(8,("dos_mode: %d %s\n", cnum, path)); + DEBUG(5,("dos_mode: %d %s\n", cnum, path)); if (CAN_WRITE(cnum) && !lp_alternate_permissions(SNUM(cnum))) { if (!((sbuf->st_mode & S_IWOTH) || @@ -241,15 +231,15 @@ int dos_mode(int cnum,char *path,struct stat *sbuf) result |= aHIDDEN; } - DEBUG(8,("dos_mode returning ")); + DEBUG(5,("dos_mode returning ")); - if (result & aHIDDEN) DEBUG(8, ("h")); - if (result & aRONLY ) DEBUG(8, ("r")); - if (result & aSYSTEM) DEBUG(8, ("s")); - if (result & aDIR ) DEBUG(8, ("d")); - if (result & aARCH ) DEBUG(8, ("a")); + if (result & aHIDDEN) DEBUG(5, ("h")); + if (result & aRONLY ) DEBUG(5, ("r")); + if (result & aSYSTEM) DEBUG(5, ("s")); + if (result & aDIR ) DEBUG(5, ("d")); + if (result & aARCH ) DEBUG(5, ("a")); - DEBUG(8,("\n")); + DEBUG(5,("\n")); return(result); } @@ -713,7 +703,15 @@ int disk_free(char *path,int *bsize,int *dfree,int *dsize) dfree_retval : dfreeq_retval ; /* maybe dfree and dfreeq are calculated using different bsizes so convert dfree from bsize into bsizeq */ - *dfree = ((*dfree) * (*bsize)) / (bsizeq); + /* avoid overflows due to multiplication, so do not: + *dfree = ((*dfree) * (*bsize)) / (bsizeq); + bsize and bsizeq are powers of 2 so its better to + to divide them getting a multiplication or division factor + for dfree. Rene Nieuwenhuizen (07-10-1997) */ + if (*bsize >= bsizeq) + *dfree = *dfree * (*bsize / bsizeq); + else + *dfree = *dfree / (bsizeq / *bsize); *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ; *bsize = bsizeq; *dsize = dsizeq; @@ -803,7 +801,15 @@ if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024; dfree_retval : dfreeq_retval ; /* maybe dfree and dfreeq are calculated using different bsizes so convert dfree from bsize into bsizeq */ - *dfree = ((*dfree) * (*bsize)) / (bsizeq); + /* avoid overflows due to multiplication, so do not: + *dfree = ((*dfree) * (*bsize)) / (bsizeq); + bsize and bsizeq are powers of 2 so its better to + to divide them getting a multiplication or division factor + for dfree. Rene Nieuwenhuizen (07-10-1997) */ + if (*bsize >= bsizeq) + *dfree = *dfree * (*bsize / bsizeq); + else + *dfree = *dfree / (bsizeq / *bsize); *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ; *bsize = bsizeq; *dsize = dsizeq; @@ -886,7 +892,8 @@ static void check_for_pipe(char *fname) /**************************************************************************** fd support routines - attempt to do a sys_open ****************************************************************************/ -static int fd_attempt_open(char *fname, int flags, int mode) + +int fd_attempt_open(char *fname, int flags, int mode) { int fd = sys_open(fname,flags,mode); @@ -938,7 +945,7 @@ static int fd_attempt_open(char *fname, int flags, int mode) fd support routines - attempt to find an already open file by dev and inode - increments the ref_count of the returned file_fd_struct *. ****************************************************************************/ -static file_fd_struct *fd_get_already_open(struct stat *sbuf) +file_fd_struct *fd_get_already_open(struct stat *sbuf) { int i; file_fd_struct *fd_ptr; @@ -965,7 +972,7 @@ static file_fd_struct *fd_get_already_open(struct stat *sbuf) fd support routines - attempt to find a empty slot in the FileFd array. Increments the ref_count of the returned entry. ****************************************************************************/ -static file_fd_struct *fd_get_new() +file_fd_struct *fd_get_new() { int i; file_fd_struct *fd_ptr; @@ -998,7 +1005,8 @@ n")); fd support routines - attempt to re-open an already open fd as O_RDWR. Save the already open fd (we cannot close due to POSIX file locking braindamage. ****************************************************************************/ -static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr) + +void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr) { int fd = sys_open( fname, O_RDWR, mode); @@ -1018,7 +1026,7 @@ static void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr) fd support routines - attempt to close the file referenced by this fd. Decrements the ref_count and returns it. ****************************************************************************/ -static int fd_attempt_close(file_fd_struct *fd_ptr) +int fd_attempt_close(file_fd_struct *fd_ptr) { DEBUG(3,("fd_attempt_close on file_fd_struct %d, fd = %d, dev = %x, inode = %x, open_flags = %d, ref_count = %d.\n", fd_ptr - &FileFd[0], @@ -1054,11 +1062,9 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct pstring fname; struct stat statbuf; file_fd_struct *fd_ptr; - files_struct *fsp = &Files[fnum]; - fsp->open = False; - fsp->fd_ptr = 0; - fsp->granted_oplock = False; + Files[fnum].open = False; + Files[fnum].fd_ptr = 0; errno = EPERM; pstrcpy(fname,fname1); @@ -1196,7 +1202,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct if (sys_disk_free(dname,&dum1,&dum2,&dum3) < lp_minprintspace(SNUM(cnum))) { fd_attempt_close(fd_ptr); - fsp->fd_ptr = 0; + Files[fnum].fd_ptr = 0; if(fd_ptr->ref_count == 0) sys_unlink(fname); errno = ENOSPC; @@ -1232,26 +1238,25 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct fd_ptr->dev = (uint32)sbuf->st_dev; fd_ptr->inode = (uint32)sbuf->st_ino; - fsp->fd_ptr = fd_ptr; + Files[fnum].fd_ptr = fd_ptr; Connections[cnum].num_files_open++; - fsp->mode = sbuf->st_mode; - GetTimeOfDay(&fsp->open_time); - fsp->uid = current_user.id; - fsp->size = 0; - fsp->pos = -1; - fsp->open = True; - fsp->mmap_ptr = NULL; - fsp->mmap_size = 0; - fsp->can_lock = True; - fsp->can_read = ((flags & O_WRONLY)==0); - fsp->can_write = ((flags & (O_WRONLY|O_RDWR))!=0); - fsp->share_mode = 0; - fsp->print_file = Connections[cnum].printer; - fsp->modified = False; - fsp->granted_oplock = False; - fsp->cnum = cnum; - string_set(&fsp->name,dos_to_unix(fname,False)); - fsp->wbmpx_ptr = NULL; + Files[fnum].mode = sbuf->st_mode; + GetTimeOfDay(&Files[fnum].open_time); + Files[fnum].uid = current_user.id; + Files[fnum].size = 0; + Files[fnum].pos = -1; + Files[fnum].open = True; + Files[fnum].mmap_ptr = NULL; + Files[fnum].mmap_size = 0; + Files[fnum].can_lock = True; + Files[fnum].can_read = ((flags & O_WRONLY)==0); + Files[fnum].can_write = ((flags & (O_WRONLY|O_RDWR))!=0); + Files[fnum].share_mode = 0; + Files[fnum].print_file = Connections[cnum].printer; + Files[fnum].modified = False; + Files[fnum].cnum = cnum; + string_set(&Files[fnum].name,dos_to_unix(fname,False)); + Files[fnum].wbmpx_ptr = NULL; /* * If the printer is marked as postscript output a leading @@ -1260,8 +1265,8 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct * This has a similar effect as CtrlD=0 in WIN.INI file. * tim@fsg.com 09/06/94 */ - if (fsp->print_file && POSTSCRIPT(cnum) && - fsp->can_write) + if (Files[fnum].print_file && POSTSCRIPT(cnum) && + Files[fnum].can_write) { DEBUG(3,("Writing postscript line\n")); write_file(fnum,"%!\n",3); @@ -1269,23 +1274,23 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct DEBUG(2,("%s %s opened file %s read=%s write=%s (numopen=%d fnum=%d)\n", timestring(),Connections[cnum].user,fname, - BOOLSTR(fsp->can_read),BOOLSTR(fsp->can_write), + BOOLSTR(Files[fnum].can_read),BOOLSTR(Files[fnum].can_write), Connections[cnum].num_files_open,fnum)); } #if USE_MMAP /* mmap it if read-only */ - if (!fsp->can_write) + if (!Files[fnum].can_write) { - fsp->mmap_size = file_size(fname); - fsp->mmap_ptr = (char *)mmap(NULL,fsp->mmap_size, - PROT_READ,MAP_SHARED,fsp->fd_ptr->fd,0); + Files[fnum].mmap_size = file_size(fname); + Files[fnum].mmap_ptr = (char *)mmap(NULL,Files[fnum].mmap_size, + PROT_READ,MAP_SHARED,Files[fnum].fd_ptr->fd,0); - if (fsp->mmap_ptr == (char *)-1 || !fsp->mmap_ptr) + if (Files[fnum].mmap_ptr == (char *)-1 || !Files[fnum].mmap_ptr) { DEBUG(3,("Failed to mmap() %s - %s\n",fname,strerror(errno))); - fsp->mmap_ptr = NULL; + Files[fnum].mmap_ptr = NULL; } } #endif @@ -1343,8 +1348,13 @@ static void check_magic(int fnum,int cnum) /**************************************************************************** close a file - possibly invalidating the read prediction + +If normal_close is 1 then this came from a normal SMBclose (or equivalent) +operation otherwise it came as the result of some other operation such as +the closing of the connection. In the latter case printing and +magic scripts are not run ****************************************************************************/ -void close_file(int fnum) +void close_file(int fnum, int normal_close) { files_struct *fs_p = &Files[fnum]; int cnum = fs_p->cnum; @@ -1356,17 +1366,17 @@ void close_file(int fnum) fs_p->open = False; Connections[cnum].num_files_open--; if(fs_p->wbmpx_ptr) - { - free((char *)fs_p->wbmpx_ptr); - fs_p->wbmpx_ptr = NULL; - } + { + free((char *)fs_p->wbmpx_ptr); + fs_p->wbmpx_ptr = NULL; + } #if USE_MMAP if(fs_p->mmap_ptr) - { - munmap(fs_p->mmap_ptr,fs_p->mmap_size); - fs_p->mmap_ptr = NULL; - } + { + munmap(fs_p->mmap_ptr,fs_p->mmap_size); + fs_p->mmap_ptr = NULL; + } #endif if (lp_share_modes(SNUM(cnum))) @@ -1381,11 +1391,12 @@ void close_file(int fnum) unlock_share_entry( cnum, dev, inode, token); /* NT uses smbclose to start a print - weird */ - if (fs_p->print_file) + if (normal_close && fs_p->print_file) print_file(fnum); /* check for magic scripts */ - check_magic(fnum,cnum); + if (normal_close) + check_magic(fnum,cnum); DEBUG(2,("%s %s closed file %s (numopen=%d)\n", timestring(),Connections[cnum].user,fs_p->name, @@ -1403,8 +1414,7 @@ static int access_table(int new_deny,int old_deny,int old_mode, if (new_deny == DENY_ALL || old_deny == DENY_ALL) return(AFAIL); if (new_deny == DENY_DOS || old_deny == DENY_DOS) { - int pid = getpid(); - if (old_deny == new_deny && share_pid == pid) + if (old_deny == new_deny && share_pid == getpid()) return(AALL); if (old_mode == 0) return(AREAD); @@ -1458,76 +1468,23 @@ BOOL check_file_sharing(int cnum,char *fname) struct stat sbuf; share_lock_token token; int pid = getpid(); - uint32 dev, inode; if(!lp_share_modes(SNUM(cnum))) return True; if (stat(fname,&sbuf) == -1) return(True); - dev = (uint32)sbuf.st_dev; - inode = (uint32)sbuf.st_ino; - - lock_share_entry(cnum, dev, inode, &token); - num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares); + lock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &token); + num_share_modes = get_share_modes(cnum, token, + (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, &old_shares); - /* - * Check if the share modes will give us access. - */ - - if(num_share_modes != 0) + for( i = 0; i < num_share_modes; i++) { - BOOL broke_oplock; - - do - { - - broke_oplock = False; - for(i = 0; i < num_share_modes; i++) - { - min_share_mode_entry *share_entry = &old_shares[i]; - -#ifdef USE_OPLOCKS - /* - * Break oplocks before checking share modes. See comment in - * open_file_shared for details. - * Check if someone has an oplock on this file. If so we must - * break it before continuing. - */ - if(share_entry->op_type & BATCH_OPLOCK) - { - - DEBUG(5,("check_file_sharing: breaking oplock (%x) on file %s, \ -dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode)); - - /* Oplock break.... */ - unlock_share_entry(cnum, dev, inode, token); - if(request_oplock_break(share_entry, dev, inode) == False) - { - free((char *)old_shares); - DEBUG(0,("check_file_sharing: FAILED when breaking oplock (%x) on file %s, \ -dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode)); - return False; - } - lock_share_entry(cnum, dev, inode, &token); - broke_oplock = True; - break; - } -#endif /* USE_OPLOCKS */ - - /* someone else has a share lock on it, check to see - if we can too */ - if ((share_entry->share_mode != DENY_DOS) || (share_entry->pid != pid)) - goto free_and_exit; + if (old_shares[i].share_mode != DENY_DOS) + goto free_and_exit; - } /* end for */ - - if(broke_oplock) - { - free((char *)old_shares); - num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares); - } - } while(broke_oplock); + if(old_shares[i].pid != pid) + goto free_and_exit; } /* XXXX exactly what share mode combinations should be allowed for @@ -1538,7 +1495,7 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode)); free_and_exit: - unlock_share_entry(cnum, dev, inode, token); + unlock_share_entry(cnum, (uint32)sbuf.st_dev, (uint32)sbuf.st_ino, token); if(old_shares != NULL) free((char *)old_shares); return(ret); @@ -1559,7 +1516,7 @@ static void truncate_unless_locked(int fnum, int cnum, share_lock_token token, if (*share_locked && lp_share_modes(SNUM(cnum))) unlock_share_entry( cnum, Files[fnum].fd_ptr->dev, Files[fnum].fd_ptr->inode, token); - close_file(fnum); + close_file(fnum, 0); /* Share mode no longer locked. */ *share_locked = False; errno = EACCES; @@ -1571,52 +1528,12 @@ static void truncate_unless_locked(int fnum, int cnum, share_lock_token token, } } -/**************************************************************************** -check if we can open a file with a share mode -****************************************************************************/ -int check_share_mode( min_share_mode_entry *share, int deny_mode, char *fname, - BOOL fcbopen, int *flags) -{ - int old_open_mode = share->share_mode &0xF; - int old_deny_mode = (share->share_mode >>4)&7; - - if (old_deny_mode > 4 || old_open_mode > 2) - { - DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n", - deny_mode,old_deny_mode,old_open_mode,fname)); - return False; - } - - { - int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode, - share->pid,fname); - - if ((access_allowed == AFAIL) || - (!fcbopen && (access_allowed == AREAD && *flags == O_RDWR)) || - (access_allowed == AREAD && *flags == O_WRONLY) || - (access_allowed == AWRITE && *flags == O_RDONLY)) - { - DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n", - deny_mode,old_deny_mode,old_open_mode, - share->pid,fname, access_allowed)); - return False; - } - - if (access_allowed == AREAD) - *flags = O_RDONLY; - - if (access_allowed == AWRITE) - *flags = O_WRONLY; - - } - return True; -} /**************************************************************************** open a file with a share mode ****************************************************************************/ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, - int mode,int oplock_request, int *Access,int *action) + int mode,int *Access,int *action) { files_struct *fs_p = &Files[fnum]; int flags=0; @@ -1629,7 +1546,6 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, share_lock_token token; uint32 dev = 0; uint32 inode = 0; - int num_share_modes = 0; fs_p->open = False; fs_p->fd_ptr = 0; @@ -1701,88 +1617,69 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, if (lp_share_modes(SNUM(cnum))) { + int num_shares = 0; int i; min_share_mode_entry *old_shares = 0; + if (file_existed) { dev = (uint32)sbuf.st_dev; inode = (uint32)sbuf.st_ino; lock_share_entry(cnum, dev, inode, &token); share_locked = True; - num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares); + num_shares = get_share_modes(cnum, token, dev, inode, &old_shares); } - /* - * Check if the share modes will give us access. - */ - - if(share_locked && (num_share_modes != 0)) + for(i = 0; i < num_shares; i++) { - BOOL broke_oplock; + /* someone else has a share lock on it, check to see + if we can too */ + int old_open_mode = old_shares[i].share_mode &0xF; + int old_deny_mode = (old_shares[i].share_mode >>4)&7; - do + if (old_deny_mode > 4 || old_open_mode > 2) { + DEBUG(0,("Invalid share mode found (%d,%d,%d) on file %s\n", + deny_mode,old_deny_mode,old_open_mode,fname)); + free((char *)old_shares); + if(share_locked) + unlock_share_entry(cnum, dev, inode, token); + errno = EACCES; + unix_ERR_class = ERRDOS; + unix_ERR_code = ERRbadshare; + return; + } - broke_oplock = False; - for(i = 0; i < num_share_modes; i++) - { - min_share_mode_entry *share_entry = &old_shares[i]; - -#ifdef USE_OPLOCKS - /* - * By observation of NetBench, oplocks are broken *before* share - * modes are checked. This allows a file to be closed by the client - * if the share mode would deny access and the client has an oplock. - * Check if someone has an oplock on this file. If so we must break - * it before continuing. - */ - if(share_entry->op_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) - { - - DEBUG(5,("open_file_shared: breaking oplock (%x) on file %s, \ -dev = %x, inode = %x\n", share_entry->op_type, fname, dev, inode)); - - /* Oplock break.... */ - unlock_share_entry(cnum, dev, inode, token); - if(request_oplock_break(share_entry, dev, inode) == False) - { - free((char *)old_shares); - DEBUG(0,("open_file_shared: FAILED when breaking oplock (%x) on file %s, \ -dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode)); - errno = EACCES; - unix_ERR_class = ERRDOS; - unix_ERR_code = ERRbadshare; - return; - } - lock_share_entry(cnum, dev, inode, &token); - broke_oplock = True; - break; - } -#endif /* USE_OPLOCKS */ - - /* someone else has a share lock on it, check to see - if we can too */ - if(check_share_mode(share_entry, deny_mode, fname, fcbopen, &flags) == False) - { - free((char *)old_shares); - unlock_share_entry(cnum, dev, inode, token); - errno = EACCES; - unix_ERR_class = ERRDOS; - unix_ERR_code = ERRbadshare; - return; - } - - } /* end for */ + { + int access_allowed = access_table(deny_mode,old_deny_mode,old_open_mode, + old_shares[i].pid,fname); - if(broke_oplock) + if ((access_allowed == AFAIL) || + (!fcbopen && (access_allowed == AREAD && flags == O_RDWR)) || + (access_allowed == AREAD && flags == O_WRONLY) || + (access_allowed == AWRITE && flags == O_RDONLY)) { + DEBUG(2,("Share violation on file (%d,%d,%d,%d,%s) = %d\n", + deny_mode,old_deny_mode,old_open_mode, + old_shares[i].pid,fname, + access_allowed)); free((char *)old_shares); - num_share_modes = get_share_modes(cnum, token, dev, inode, &old_shares); + if(share_locked) + unlock_share_entry(cnum, dev, inode, token); + errno = EACCES; + unix_ERR_class = ERRDOS; + unix_ERR_code = ERRbadshare; + return; } - } while(broke_oplock); + + if (access_allowed == AREAD) + flags = O_RDONLY; + + if (access_allowed == AWRITE) + flags = O_WRONLY; + } } - if(old_shares != 0) free((char *)old_shares); } @@ -1839,35 +1736,7 @@ dev = %x, inode = %x\n", old_shares[i].op_type, fname, dev, inode)); file (which expects the share_mode_entry to be there). */ if (lp_share_modes(SNUM(cnum))) - { - uint16 port = 0; -#ifdef USE_OPLOCKS - /* JRA. Currently this only services Exlcusive and batch - oplocks (no other opens on this file). This needs to - be extended to level II oplocks (multiple reader - oplocks). */ - - if(oplock_request && (num_share_modes == 0) && lp_oplocks(SNUM(cnum))) - { - fs_p->granted_oplock = True; - global_oplocks_open++; - port = oplock_port; - - DEBUG(5,("open_file_shared: granted oplock (%x) on file %s, \ -dev = %x, inode = %x\n", oplock_request, fname, dev, inode)); - - } - else - { - port = 0; - oplock_request = 0; - } -#else /* USE_OPLOCKS */ - oplock_request = 0; - port = 0; -#endif /* USE_OPLOCKS */ - set_share_mode(token, fnum, port, oplock_request); - } + set_share_mode(token, fnum); if ((flags2&O_TRUNC) && file_existed) truncate_unless_locked(fnum,cnum,token,&share_locked); @@ -2116,7 +1985,11 @@ struct {EPERM,ERRDOS,ERRnoaccess}, {EACCES,ERRDOS,ERRnoaccess}, {ENOENT,ERRDOS,ERRbadfile}, +#if 0 /* Go back to old method for now. */ + {ENOTDIR,ERRDOS,ERRbaddirectory}, +#else {ENOTDIR,ERRDOS,ERRbadpath}, +#endif {EIO,ERRHRD,ERRgeneral}, {EBADF,ERRSRV,ERRsrverror}, {EINVAL,ERRSRV,ERRsrverror}, @@ -2137,6 +2010,23 @@ struct {0,0,0} }; +#if 0 /* Go back to old method for now. */ +/* Mapping for old clients. */ + +struct +{ + int new_smb_error; + int old_smb_error; + int protocol_level; + enum remote_arch_types valid_ra_type; +} old_client_errmap[] = +{ + {ERRbaddirectory, ERRbadpath, (int)PROTOCOL_NT1, RA_WINNT}, + {0,0,0} +}; + +#endif /* Go back to old method for now. */ + /**************************************************************************** create an error packet from errno ****************************************************************************/ @@ -2167,6 +2057,32 @@ int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int } } +#if 0 /* Go back to old method for now. */ + + /* Make sure we don't return error codes that old + clients don't understand. */ + + /* JRA - unfortunately, WinNT needs some error codes + for apps to work correctly, Win95 will break if + these error codes are returned. But they both + negotiate the *same* protocol. So we need to use + the revolting 'remote_arch' enum to tie break. + + There must be a better way of doing this... + */ + + for(i = 0; old_client_errmap[i].new_smb_error != 0; i++) + { + if(((Protocol < old_client_errmap[i].protocol_level) || + (old_client_errmap[i].valid_ra_type != get_remote_arch())) && + (old_client_errmap[i].new_smb_error == ecode)) + { + ecode = old_client_errmap[i].old_smb_error; + break; + } + } +#endif /* Go back to old method for now. */ + return(error_packet(inbuf,outbuf,eclass,ecode,line)); } @@ -2373,516 +2289,6 @@ static BOOL open_sockets(BOOL is_daemon,int port) return True; } -/**************************************************************************** - process an smb from the client - split out from the process() code so - it can be used by the oplock break code. -****************************************************************************/ - -static void process_smb(char *inbuf, char *outbuf) -{ - extern int Client; - static int trans_num; - int msg_type = CVAL(inbuf,0); - int32 len = smb_len(inbuf); - int nread = len + 4; - - if (trans_num == 0) { - /* on the first packet, check the global hosts allow/ hosts - deny parameters before doing any parsing of the packet - passed to us by the client. This prevents attacks on our - parsing code from hosts not in the hosts allow list */ - if (!check_access(-1)) { - /* send a negative session response "not listining on calling - name" */ - static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81}; - DEBUG(1,("%s Connection denied from %s\n", - timestring(),client_addr())); - send_smb(Client,(char *)buf); - exit_server("connection denied"); - } - } - - DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len)); - DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread)); - -#ifdef WITH_VTP - if(trans_num == 1 && VT_Check(inbuf)) - { - VT_Process(); - return; - } -#endif - - if (msg_type == 0) - show_msg(inbuf); - - nread = construct_reply(inbuf,outbuf,nread,max_send); - - if(nread > 0) - { - if (CVAL(outbuf,0) == 0) - show_msg(outbuf); - - if (nread != smb_len(outbuf) + 4) - { - DEBUG(0,("ERROR: Invalid message response size! %d %d\n", - nread, smb_len(outbuf))); - } - else - send_smb(Client,outbuf); - } - trans_num++; -} - -#ifdef USE_OPLOCKS -/**************************************************************************** - open the oplock IPC socket communication -****************************************************************************/ -static BOOL open_oplock_ipc() -{ - struct sockaddr_in sock_name; - int name_len = sizeof(sock_name); - - DEBUG(3,("open_oplock_ipc: opening loopback UDP socket.\n")); - - /* Open a lookback UDP socket on a random port. */ - oplock_sock = open_socket_in(SOCK_DGRAM, 0, 0, htonl(INADDR_LOOPBACK)); - if (oplock_sock == -1) - { - DEBUG(0,("open_oplock_ipc: Failed to get local UDP socket for \ -address %x. Error was %s\n", htonl(INADDR_LOOPBACK), strerror(errno))); - oplock_port = 0; - return(False); - } - - /* Find out the transient UDP port we have been allocated. */ - if(getsockname(oplock_sock, (struct sockaddr *)&sock_name, &name_len)<0) - { - DEBUG(0,("open_oplock_ipc: Failed to get local UDP port. Error was %s\n", - strerror(errno))); - close(oplock_sock); - oplock_sock = -1; - oplock_port = 0; - return False; - } - oplock_port = ntohs(sock_name.sin_port); - - return True; -} - -/**************************************************************************** - process an oplock break message. -****************************************************************************/ -static BOOL process_local_message(int oplock_sock, char *buffer, int buf_size) -{ - int32 msg_len; - int16 from_port; - char *msg_start; - - msg_len = IVAL(buffer,UDP_CMD_LEN_OFFSET); - from_port = SVAL(buffer,UDP_CMD_PORT_OFFSET); - - msg_start = &buffer[UDP_CMD_HEADER_LEN]; - - DEBUG(5,("process_local_message: Got a message of length %d from port (%d)\n", - msg_len, from_port)); - - /* Switch on message command - currently OPLOCK_BREAK_CMD is the - only valid request. */ - - switch(SVAL(msg_start,UDP_MESSAGE_CMD_OFFSET)) - { - case OPLOCK_BREAK_CMD: - /* Ensure that the msg length is correct. */ - if(msg_len != OPLOCK_BREAK_MSG_LEN) - { - DEBUG(0,("process_local_message: incorrect length for OPLOCK_BREAK_CMD (was %d, \ -should be %d).\n", msg_len, OPLOCK_BREAK_MSG_LEN)); - return False; - } - { - uint32 remotepid = IVAL(msg_start,OPLOCK_BREAK_PID_OFFSET); - uint32 dev = IVAL(msg_start,OPLOCK_BREAK_DEV_OFFSET); - uint32 inode = IVAL(msg_start, OPLOCK_BREAK_INODE_OFFSET); - struct timeval tval; - struct sockaddr_in toaddr; - - tval.tv_sec = IVAL(msg_start, OPLOCK_BREAK_SEC_OFFSET); - tval.tv_usec = IVAL(msg_start, OPLOCK_BREAK_USEC_OFFSET); - - DEBUG(5,("process_local_message: oplock break request from \ -pid %d, port %d, dev = %x, inode = %x\n", remotepid, from_port, dev, inode)); - - /* - * If we have no record of any currently open oplocks, - * it's not an error, as a close command may have - * just been issued on the file that was oplocked. - * Just return success in this case. - */ - - if(global_oplocks_open != 0) - { - if(oplock_break(dev, inode, &tval) == False) - { - DEBUG(0,("process_local_message: oplock break failed - \ -not returning udp message.\n")); - return False; - } - } - else - { - DEBUG(3,("process_local_message: oplock break requested with no outstanding \ -oplocks. Returning success.\n")); - } - - /* Send the message back after OR'ing in the 'REPLY' bit. */ - SSVAL(msg_start,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD | CMD_REPLY); - - bzero((char *)&toaddr,sizeof(toaddr)); - toaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - toaddr.sin_port = htons(from_port); - toaddr.sin_family = AF_INET; - - if(sendto( oplock_sock, msg_start, OPLOCK_BREAK_MSG_LEN, 0, - (struct sockaddr *)&toaddr, sizeof(toaddr)) < 0) - { - DEBUG(0,("process_local_message: sendto process %d failed. Errno was %s\n", - remotepid, strerror(errno))); - return False; - } - - DEBUG(5,("process_local_message: oplock break reply sent to \ -pid %d, port %d, for file dev = %x, inode = %x\n", remotepid, - from_port, dev, inode)); - - } - break; - default: - DEBUG(0,("process_local_message: unknown UDP message command code (%x) - ignoring.\n", - (unsigned int)SVAL(msg_start,0))); - return False; - } - return True; -} - -/**************************************************************************** - Process an oplock break directly. -****************************************************************************/ -BOOL oplock_break(uint32 dev, uint32 inode, struct timeval *tval) -{ - extern int Client; - static char *inbuf = NULL; - static char *outbuf = NULL; - files_struct *fsp = NULL; - int fnum; - time_t start_time; - BOOL shutdown_server = False; - - DEBUG(5,("oplock_break: called for dev = %x, inode = %x. Current \ -global_oplocks_open = %d\n", dev, inode, global_oplocks_open)); - - if(inbuf == NULL) - { - inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); - if(inbuf == NULL) { - DEBUG(0,("oplock_break: malloc fail for input buffer.\n")); - return False; - } - outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); - if(outbuf == NULL) { - DEBUG(0,("oplock_break: malloc fail for output buffer.\n")); - free(inbuf); - inbuf = NULL; - return False; - } - } - - /* We need to search the file open table for the - entry containing this dev and inode, and ensure - we have an oplock on it. */ - for( fnum = 0; fnum < MAX_OPEN_FILES; fnum++) - { - if(OPEN_FNUM(fnum)) - { - fsp = &Files[fnum]; - if((fsp->fd_ptr->dev == dev) && (fsp->fd_ptr->inode == inode) && - (fsp->open_time.tv_sec == tval->tv_sec) && - (fsp->open_time.tv_usec == tval->tv_usec)) - break; - } - } - - if(fsp == NULL) - { - /* The file could have been closed in the meantime - return success. */ - DEBUG(3,("oplock_break: cannot find open file with dev = %x, inode = %x (fnum = %d) \ -allowing break to succeed.\n", dev, inode, fnum)); - return True; - } - - /* Ensure we have an oplock on the file */ - - /* There is a potential race condition in that an oplock could - have been broken due to another udp request, and yet there are - still oplock break messages being sent in the udp message - queue for this file. So return true if we don't have an oplock, - as we may have just freed it. - */ - - if(!fsp->granted_oplock) - { - DEBUG(3,("oplock_break: file %s (fnum = %d, dev = %x, inode = %x) has no oplock. \ -Allowing break to succeed regardless.\n", fsp->name, fnum, dev, inode)); - return True; - } - - /* Now comes the horrid part. We must send an oplock break to the client, - and then process incoming messages until we get a close or oplock release. - */ - - /* Prepare the SMBlockingX message. */ - bzero(outbuf,smb_size); - set_message(outbuf,8,0,True); - - SCVAL(outbuf,smb_com,SMBlockingX); - SSVAL(outbuf,smb_tid,fsp->cnum); - SSVAL(outbuf,smb_pid,0xFFFF); - SSVAL(outbuf,smb_uid,0); - SSVAL(outbuf,smb_mid,0xFFFF); - SCVAL(outbuf,smb_vwv0,0xFF); - SSVAL(outbuf,smb_vwv2,fnum); - SCVAL(outbuf,smb_vwv3,LOCKING_ANDX_OPLOCK_RELEASE); - /* Change this when we have level II oplocks. */ - SCVAL(outbuf,smb_vwv3+1,OPLOCKLEVEL_NONE); - - send_smb(Client, outbuf); - - global_oplock_break = True; - - /* Process incoming messages. */ - - /* JRA - If we don't get a break from the client in OPLOCK_BREAK_TIMEOUT - seconds we should just die.... */ - - start_time = time(NULL); - - while(OPEN_FNUM(fnum) && fsp->granted_oplock) - { - if(receive_smb(Client,inbuf,OPLOCK_BREAK_TIMEOUT * 1000) == False) - { - /* - * Die if we got an error. - */ - - if (smb_read_error == READ_EOF) - DEBUG(0,("oplock_break: end of file from client\n")); - - if (smb_read_error == READ_ERROR) - DEBUG(0,("oplock_break: receive_smb error (%s)\n", - strerror(errno))); - - if (smb_read_error == READ_TIMEOUT) - DEBUG(0,("oplock_break: receive_smb timed out after %d seconds.\n", - OPLOCK_BREAK_TIMEOUT)); - - DEBUG(0,("oplock_break failed for file %s (fnum = %d, dev = %x, \ -inode = %x).\n", fsp->name, fnum, dev, inode)); - shutdown_server = True; - break; - } - process_smb(inbuf, outbuf); - - /* We only need this in case a readraw crossed on the wire. */ - if(global_oplock_break) - global_oplock_break = False; - - /* - * Die if we go over the time limit. - */ - - if((time(NULL) - start_time) > OPLOCK_BREAK_TIMEOUT) - { - DEBUG(0,("oplock_break: no break received from client within \ -%d seconds.\n", OPLOCK_BREAK_TIMEOUT)); - DEBUG(0,("oplock_break failed for file %s (fnum = %d, dev = %x, \ -inode = %x).\n", fsp->name, fnum, dev, inode)); - shutdown_server = True; - break; - } - } - - /* - * If the client did not respond we must die. - */ - - if(shutdown_server) - { - DEBUG(0,("oplock_break: client failure in break - shutting down this smbd.\n")); - close_sockets(); - close(oplock_sock); - exit_server("oplock break failure"); - } - - if(OPEN_FNUM(fnum)) - { - /* The lockingX reply will have removed the oplock flag - from the sharemode. */ - /* Paranoia.... */ - fsp->granted_oplock = False; - } - - global_oplocks_open--; - - /* Santity check - remove this later. JRA */ - if(global_oplocks_open < 0) - { - DEBUG(0,("oplock_break: global_oplocks_open < 0 (%d). PANIC ERROR\n", - global_oplocks_open)); - abort(); - } - - DEBUG(5,("oplock_break: returning success for fnum = %d, dev = %x, inode = %x. Current \ -global_oplocks_open = %d\n", fnum, dev, inode, global_oplocks_open)); - - return True; -} - -/**************************************************************************** -Send an oplock break message to another smbd process. If the oplock is held -by the local smbd then call the oplock break function directly. -****************************************************************************/ - -BOOL request_oplock_break(min_share_mode_entry *share_entry, - uint32 dev, uint32 inode) -{ - char op_break_msg[OPLOCK_BREAK_MSG_LEN]; - struct sockaddr_in addr_out; - int pid = getpid(); - - if(pid == share_entry->pid) - { - /* We are breaking our own oplock, make sure it's us. */ - if(share_entry->op_port != oplock_port) - { - DEBUG(0,("request_oplock_break: corrupt share mode entry - pid = %d, port = %d \ -should be %d\n", pid, share_entry->op_port, oplock_port)); - return False; - } - - DEBUG(5,("request_oplock_break: breaking our own oplock\n")); - - /* Call oplock break direct. */ - return oplock_break(dev, inode, &share_entry->time); - } - - /* We need to send a OPLOCK_BREAK_CMD message to the - port in the share mode entry. */ - - SSVAL(op_break_msg,UDP_MESSAGE_CMD_OFFSET,OPLOCK_BREAK_CMD); - SIVAL(op_break_msg,OPLOCK_BREAK_PID_OFFSET,pid); - SIVAL(op_break_msg,OPLOCK_BREAK_DEV_OFFSET,dev); - SIVAL(op_break_msg,OPLOCK_BREAK_INODE_OFFSET,inode); - SIVAL(op_break_msg,OPLOCK_BREAK_SEC_OFFSET,(uint32)share_entry->time.tv_sec); - SIVAL(op_break_msg,OPLOCK_BREAK_USEC_OFFSET,(uint32)share_entry->time.tv_usec); - - /* set the address and port */ - bzero((char *)&addr_out,sizeof(addr_out)); - addr_out.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - addr_out.sin_port = htons( share_entry->op_port ); - addr_out.sin_family = AF_INET; - - DEBUG(3,("request_oplock_break: sending a oplock break message to pid %d on port %d \ -for dev = %x, inode = %x\n", share_entry->pid, share_entry->op_port, dev, inode)); - - if(sendto(oplock_sock,op_break_msg,OPLOCK_BREAK_MSG_LEN,0, - (struct sockaddr *)&addr_out,sizeof(addr_out)) < 0) - { - DEBUG(0,("request_oplock_break: failed when sending a oplock break message \ -to pid %d on port %d for dev = %x, inode = %x. Error was %s\n", - share_entry->pid, share_entry->op_port, dev, inode, - strerror(errno))); - return False; - } - - /* - * Now we must await the oplock broken message coming back - * from the target smbd process. Timeout if it fails to - * return in OPLOCK_BREAK_TIMEOUT seconds. - * While we get messages that aren't ours, loop. - */ - - while(1) - { - char op_break_reply[UDP_CMD_HEADER_LEN+OPLOCK_BREAK_MSG_LEN]; - int32 reply_msg_len; - int16 reply_from_port; - char *reply_msg_start; - - if(receive_local_message(oplock_sock, op_break_reply, sizeof(op_break_reply), - OPLOCK_BREAK_TIMEOUT * 1000) == False) - { - if(smb_read_error == READ_TIMEOUT) - DEBUG(0,("request_oplock_break: no response received to oplock break request to \ -pid %d on port %d for dev = %x, inode = %x\n", share_entry->pid, - share_entry->op_port, dev, inode)); - else - DEBUG(0,("request_oplock_break: error in response received to oplock break request to \ -pid %d on port %d for dev = %x, inode = %x. Error was (%s).\n", share_entry->pid, - share_entry->op_port, dev, inode, strerror(errno))); - return False; - } - - /* - * If the response we got was not an answer to our message, but - * was a completely different request, push it onto the pending - * udp message stack so that we can deal with it in the main loop. - * It may be another oplock break request to us. - */ - - /* - * Local note from JRA. There exists the possibility of a denial - * of service attack here by allowing non-root processes running - * on a local machine sending many of these pending messages to - * a smbd port. Currently I'm not sure how to restrict the messages - * I will queue (although I could add a limit to the queue) to - * those received by root processes only. There should be a - * way to make this bulletproof.... - */ - - reply_msg_len = IVAL(op_break_reply,UDP_CMD_LEN_OFFSET); - reply_from_port = SVAL(op_break_reply,UDP_CMD_PORT_OFFSET); - - reply_msg_start = &op_break_reply[UDP_CMD_HEADER_LEN]; - - if(reply_msg_len != OPLOCK_BREAK_MSG_LEN) - { - /* Ignore it. */ - DEBUG(0,("request_oplock_break: invalid message length received. Ignoring\n")); - continue; - } - - if(((SVAL(reply_msg_start,UDP_MESSAGE_CMD_OFFSET) & CMD_REPLY) == 0) || - (reply_from_port != share_entry->op_port) || - (memcmp(&reply_msg_start[OPLOCK_BREAK_PID_OFFSET], - &op_break_msg[OPLOCK_BREAK_PID_OFFSET], - OPLOCK_BREAK_MSG_LEN - OPLOCK_BREAK_PID_OFFSET) != 0)) - { - DEBUG(3,("request_oplock_break: received other message whilst awaiting \ -oplock break response from pid %d on port %d for dev = %x, inode = %x.\n", - share_entry->pid, share_entry->op_port, dev, inode)); - if(push_local_message(op_break_reply, sizeof(op_break_reply)) == False) - return False; - } - - break; - } - - DEBUG(3,("request_oplock_break: broke oplock.\n")); - - return True; -} - -#endif /* USE_OPLOCKS */ /**************************************************************************** check if a snum is in use @@ -3440,15 +2846,19 @@ int reply_lanman1(char *outbuf) set_message(outbuf,13,doencrypt?8:0,True); SSVAL(outbuf,smb_vwv1,secword); +#ifdef SMB_PASSWD /* Create a token value and add it to the outgoing packet. */ if (doencrypt) generate_next_challenge(smb_buf(outbuf)); +#endif Protocol = PROTOCOL_LANMAN1; if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) { DEBUG(3,("using password server validation\n")); +#ifdef SMB_PASSWD if (doencrypt) set_challenge(smb_buf(outbuf)); +#endif } CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */ @@ -3487,9 +2897,11 @@ int reply_lanman2(char *outbuf) set_message(outbuf,13,doencrypt?8:0,True); SSVAL(outbuf,smb_vwv1,secword); +#ifdef SMB_PASSWD /* Create a token value and add it to the outgoing packet. */ if (doencrypt) generate_next_challenge(smb_buf(outbuf)); +#endif SIVAL(outbuf,smb_vwv6,getpid()); @@ -3497,7 +2909,9 @@ int reply_lanman2(char *outbuf) if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) { DEBUG(3,("using password server validation\n")); +#ifdef SMB_PASSWD if (doencrypt) set_challenge(smb_buf(outbuf)); +#endif } CVAL(outbuf,smb_flg) = 0x81; /* Reply, SMBlockread, SMBwritelock supported */ @@ -3567,6 +2981,7 @@ int reply_nt1(char *outbuf) #endif CVAL(outbuf,smb_vwv1) = secword; +#ifdef SMB_PASSWD /* Create a token value and add it to the outgoing packet. */ if (doencrypt) { @@ -3575,12 +2990,15 @@ int reply_nt1(char *outbuf) /* Tell the nt machine how long the challenge is. */ SSVALS(outbuf,smb_vwv16+1,challenge_len); } +#endif Protocol = PROTOCOL_NT1; if (lp_security() == SEC_SERVER && server_cryptkey(outbuf)) { DEBUG(3,("using password server validation\n")); +#ifdef SMB_PASSWD if (doencrypt) set_challenge(smb_buf(outbuf)); +#endif } SSVAL(outbuf,smb_mid,mid); /* Restore possibly corrupted mid */ @@ -3791,7 +3209,7 @@ static void close_open_files(int cnum) int i; for (i=0;i<MAX_OPEN_FILES;i++) if( Files[i].cnum == cnum && Files[i].open) { - close_file(i); + close_file(i, 0); } } @@ -3804,6 +3222,10 @@ void close_cnum(int cnum, uint16 vuid) { DirCacheFlush(SNUM(cnum)); + close_open_files(cnum); + dptr_closecnum(cnum); + + /* after this we are running as root, so be careful! */ unbecome_user(); if (!OPEN_CNUM(cnum)) @@ -3824,9 +3246,6 @@ void close_cnum(int cnum, uint16 vuid) if (lp_status(SNUM(cnum))) yield_connection(cnum,"STATUS.",MAXSTATUS); - close_open_files(cnum); - dptr_closecnum(cnum); - /* execute any "postexec = " line */ if (*lp_postexec(SNUM(cnum)) && become_user(cnum,vuid)) { @@ -4556,11 +3975,14 @@ int construct_reply(char *inbuf,char *outbuf,int size,int bufsize) return(outsize); } + /**************************************************************************** process commands from the client ****************************************************************************/ static void process(void) { + static int trans_num = 0; + int nread; extern int Client; InBuffer = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); @@ -4583,36 +4005,32 @@ static void process(void) #endif while (True) - { - int deadtime = lp_deadtime()*60; - int counter; - int last_keepalive=0; - int service_load_counter = 0; -#ifdef USE_OPLOCKS - BOOL got_smb = False; -#endif /* USE_OPLOCKS */ - - if (deadtime <= 0) - deadtime = DEFAULT_SMBD_TIMEOUT; - - if (lp_readprediction()) - do_read_prediction(); - - errno = 0; - - for (counter=SMBD_SELECT_LOOP; -#ifdef USE_OPLOCKS - !receive_message_or_smb(Client,oplock_sock, - InBuffer,BUFFER_SIZE,SMBD_SELECT_LOOP*1000,&got_smb); -#else /* USE_OPLOCKS */ - !receive_smb(Client,InBuffer,SMBD_SELECT_LOOP*1000); -#endif /* USE_OPLOCKS */ - counter += SMBD_SELECT_LOOP) { - int i; - time_t t; - BOOL allidle = True; - extern int keepalive; + int32 len; + int msg_type; + int msg_flags; + int type; + int deadtime = lp_deadtime()*60; + int counter; + int last_keepalive=0; + int service_load_counter = 0; + + if (deadtime <= 0) + deadtime = DEFAULT_SMBD_TIMEOUT; + + if (lp_readprediction()) + do_read_prediction(); + + errno = 0; + + for (counter=SMBD_SELECT_LOOP; + !receive_smb(Client,InBuffer,SMBD_SELECT_LOOP*1000); + counter += SMBD_SELECT_LOOP) + { + int i; + time_t t; + BOOL allidle = True; + extern int keepalive; if (counter > 365 * 3600) /* big number of seconds. */ { @@ -4620,84 +4038,126 @@ static void process(void) service_load_counter = 0; } - if (smb_read_error == READ_EOF) - { - DEBUG(3,("end of file from client\n")); - return; - } + if (smb_read_error == READ_EOF) { + DEBUG(3,("end of file from client\n")); + return; + } - if (smb_read_error == READ_ERROR) - { - DEBUG(3,("receive_smb error (%s) exiting\n", - strerror(errno))); - return; - } + if (smb_read_error == READ_ERROR) { + DEBUG(3,("receive_smb error (%s) exiting\n", + strerror(errno))); + return; + } - t = time(NULL); + t = time(NULL); - /* become root again if waiting */ - unbecome_user(); + /* become root again if waiting */ + unbecome_user(); - /* check for smb.conf reload */ - if (counter >= service_load_counter + SMBD_RELOAD_CHECK) + /* check for smb.conf reload */ + if (counter >= service_load_counter + SMBD_RELOAD_CHECK) { service_load_counter = counter; /* reload services, if files have changed. */ - reload_services(True); + reload_services(True); } - /* automatic timeout if all connections are closed */ - if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) - { - DEBUG(2,("%s Closing idle connection\n",timestring())); - return; - } + /* automatic timeout if all connections are closed */ + if (num_connections_open==0 && counter >= IDLE_CLOSED_TIMEOUT) { + DEBUG(2,("%s Closing idle connection\n",timestring())); + return; + } - if (keepalive && (counter-last_keepalive)>keepalive) - { - extern int password_client; - if (!send_keepalive(Client)) - { - DEBUG(2,("%s Keepalive failed - exiting\n",timestring())); - return; - } - /* also send a keepalive to the password server if its still - connected */ - if (password_client != -1) - send_keepalive(password_client); - last_keepalive = counter; + if (keepalive && (counter-last_keepalive)>keepalive) { + extern int password_client; + if (!send_keepalive(Client)) { + DEBUG(2,("%s Keepalive failed - exiting\n",timestring())); + return; + } + /* also send a keepalive to the password server if its still + connected */ + if (password_client != -1) + send_keepalive(password_client); + last_keepalive = counter; + } + + /* check for connection timeouts */ + for (i=0;i<MAX_CONNECTIONS;i++) + if (Connections[i].open) + { + /* close dirptrs on connections that are idle */ + if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT) + dptr_idlecnum(i); + + if (Connections[i].num_files_open > 0 || + (t-Connections[i].lastused)<deadtime) + allidle = False; + } + + if (allidle && num_connections_open>0) { + DEBUG(2,("%s Closing idle connection 2\n",timestring())); + return; + } + } + + if (trans_num == 0) { + /* on the first packet, check the global hosts allow/ hosts + deny parameters before doing any parsing of the packet + passed to us by the client. This prevents attacks on our + parsing code from hosts not in the hosts allow list */ + if (!check_access(-1)) { + /* send a negative session response "not listining + on calling name" */ + static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81}; + DEBUG(1,("%s Connection denied from %s\n", + timestring(),client_addr())); + send_smb(Client,(char *)buf); + exit_server("connection denied"); + } } - /* check for connection timeouts */ - for (i=0;i<MAX_CONNECTIONS;i++) - if (Connections[i].open) - { - /* close dirptrs on connections that are idle */ - if ((t-Connections[i].lastused)>DPTR_IDLE_TIMEOUT) - dptr_idlecnum(i); - if (Connections[i].num_files_open > 0 || - (t-Connections[i].lastused)<deadtime) - allidle = False; - } + msg_type = CVAL(InBuffer,0); + msg_flags = CVAL(InBuffer,1); + type = CVAL(InBuffer,smb_com); - if (allidle && num_connections_open>0) - { - DEBUG(2,("%s Closing idle connection 2\n",timestring())); + len = smb_len(InBuffer); + + DEBUG(6,("got message type 0x%x of len 0x%x\n",msg_type,len)); + + nread = len + 4; + + DEBUG(3,("%s Transaction %d of length %d\n",timestring(),trans_num,nread)); + +#ifdef WITH_VTP + if(trans_num == 1 && VT_Check(InBuffer)) { + VT_Process(); return; } - } +#endif -#ifdef USE_OPLOCKS - if(got_smb) -#endif /* USE_OPLOCKS */ - process_smb(InBuffer, OutBuffer); -#ifdef USE_OPLOCKS - else - process_local_message(oplock_sock, InBuffer, BUFFER_SIZE); -#endif /* USE_OPLOCKS */ - } + + if (msg_type == 0) + show_msg(InBuffer); + + nread = construct_reply(InBuffer,OutBuffer,nread,max_send); + + if(nread > 0) { + if (CVAL(OutBuffer,0) == 0) + show_msg(OutBuffer); + + if (nread != smb_len(OutBuffer) + 4) + { + DEBUG(0,("ERROR: Invalid message response size! %d %d\n", + nread, + smb_len(OutBuffer))); + } + else + send_smb(Client,OutBuffer); + } + trans_num++; + } } @@ -4976,12 +4436,6 @@ static void usage(char *pname) DEBUG(2,("%s changed root to %s\n",timestring(),lp_rootdir())); } -#ifdef USE_OPLOCKS - /* Setup the oplock IPC socket. */ - if(!open_oplock_ipc()) - exit(1); -#endif /* USE_OPLOCKS */ - process(); close_sockets(); diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index 7f46604cce9..f7351b99e5a 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -166,7 +166,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum, char *params = *pparams; int16 open_mode = SVAL(params, 2); int16 open_attr = SVAL(params,6); - BOOL oplock_request = (((SVAL(params,0)|(1<<1))>>1) | ((SVAL(params,0)|(1<<2))>>1)); + BOOL oplock_request = BITSETW(params,1); #if 0 BOOL return_additional_info = BITSETW(params,0); int16 open_sattr = SVAL(params, 4); @@ -213,7 +213,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum, open_file_shared(fnum,cnum,fname,open_mode,open_ofun,unixmode, - oplock_request, &rmode,&smb_action); + &rmode,&smb_action); if (!Files[fnum].open) { @@ -226,7 +226,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum, } if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) { - close_file(fnum); + close_file(fnum, 0); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -235,7 +235,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum, mtime = sbuf.st_mtime; inode = sbuf.st_ino; if (fmode & aDIR) { - close_file(fnum); + close_file(fnum, 0); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -252,7 +252,7 @@ static int call_trans2open(char *inbuf, char *outbuf, int bufsize, int cnum, SSVAL(params,12,rmode); if (oplock_request && lp_fake_oplocks(SNUM(cnum))) { - smb_action |= EXTENDED_OPLOCK_GRANTED; + smb_action |= (1<<15); } SSVAL(params,18,smb_action); @@ -319,7 +319,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l reskey = TellDir(Connections[cnum].dirptr); - DEBUG(8,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n", + DEBUG(6,("get_lanman2_dir_entry:readdir on dirptr 0x%x now at offset %d\n", Connections[cnum].dirptr,TellDir(Connections[cnum].dirptr))); if (!dname) @@ -607,15 +607,6 @@ static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadpath; } - - /* Ugly - NT specific hack - but needed (JRA) */ - if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) && - (get_remote_arch() == RA_WINNT)) - { - unix_ERR_class = ERRDOS; - unix_ERR_code = ERRbaddirectory; - } - return(ERROR(ERRDOS,ERRbadpath)); } @@ -650,14 +641,6 @@ static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum unix_ERR_class = ERRDOS; unix_ERR_code = ERRbadpath; } - - /* Ugly - NT specific hack - but needed (JRA) */ - if((errno == ENOTDIR) && (Protocol >= PROTOCOL_NT1) && - (get_remote_arch() == RA_WINNT)) - { - unix_ERR_class = ERRDOS; - unix_ERR_code = ERRbaddirectory; - } return (UNIXERROR(ERRDOS,ERRbadpath)); } return(ERROR(ERRDOS,ERRbadpath)); @@ -1364,14 +1347,6 @@ static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length, tvs.modtime=MAX(interpret_long_date(pdata+16), interpret_long_date(pdata+24)); -#if 0 /* Needs more testing... */ - /* Test from Luke to prevent Win95 from - setting incorrect values here. - */ - if (tvs.actime < tvs.modtime) - return(ERROR(ERRDOS,ERRnoaccess)); -#endif /* Needs more testing... */ - /* attributes */ mode = IVAL(pdata,32); break; diff --git a/source/smbd/uid.c b/source/smbd/uid.c index cdc4e474c61..fe2cb5a652d 100644 --- a/source/smbd/uid.c +++ b/source/smbd/uid.c @@ -258,6 +258,8 @@ BOOL become_user(int cnum, uint16 vuid) if (current_user.ngroups > 0) if (setgroups(current_user.ngroups,current_user.groups)<0) DEBUG(0,("setgroups call failed!\n")); + } else { + current_user.ngroups = 0; } #endif @@ -318,7 +320,8 @@ BOOL unbecome_user(void ) current_user.uid = initial_uid; current_user.gid = initial_gid; - + current_user.ngroups = 0; + if (ChDir(OriginalDir) != 0) DEBUG(0,("%s chdir(%s) failed in unbecome_user\n", timestring(),OriginalDir)); @@ -476,3 +479,82 @@ int smbrun(char *cmd,char *outfile,BOOL shared) #endif return 1; } + + + +static struct current_user current_user_saved; +static int become_root_depth; +static pstring become_root_dir; + +/**************************************************************************** +This is used when we need to do a privilaged operation (such as mucking +with share mode files) and temporarily need root access to do it. This +call should always be paired with an unbecome_root() call immediately +after the operation + +Set save_dir if you also need to save/restore the CWD +****************************************************************************/ +void become_root(int save_dir) +{ + if (become_root_depth) { + DEBUG(0,("ERROR: become root depth is non zero\n")); + } + if (save_dir) + GetWd(become_root_dir); + + current_user_saved = current_user; + become_root_depth = 1; + + become_gid(0); + become_uid(0); +} + +/**************************************************************************** +When the privilaged operation is over call this + +Set save_dir if you also need to save/restore the CWD +****************************************************************************/ +void unbecome_root(int restore_dir) +{ + if (become_root_depth != 1) { + DEBUG(0,("ERROR: unbecome root depth is %d\n", + become_root_depth)); + } + + /* we might have done a become_user() while running as root, + if we have then become root again in order to become + non root! */ + if (current_user.uid != 0) { + become_uid(0); + } + + /* restore our gid first */ + if (!become_gid(current_user_saved.gid)) { + DEBUG(0,("ERROR: Failed to restore gid\n")); + exit_server("Failed to restore gid"); + } + +#ifndef NO_SETGROUPS + if (current_user_saved.ngroups > 0) { + if (setgroups(current_user_saved.ngroups, + current_user_saved.groups)<0) + DEBUG(0,("ERROR: setgroups call failed!\n")); + } +#endif + + /* now restore our uid */ + if (!become_uid(current_user_saved.uid)) { + DEBUG(0,("ERROR: Failed to restore uid\n")); + exit_server("Failed to restore uid"); + } + + if (restore_dir) + ChDir(become_root_dir); + + current_user = current_user_saved; + + become_root_depth = 0; +} + + + diff --git a/source/utils/make_smbcodepage.c b/source/utils/make_smbcodepage.c deleted file mode 100644 index b4cb1523349..00000000000 --- a/source/utils/make_smbcodepage.c +++ /dev/null @@ -1,472 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Create codepage files from codepage_def.XXX files. - - Copyright (C) Jeremy Allison 1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -static char *prog_name = NULL; - -/* - * Print program usage and die. - */ - -void codepage_usage(char *progname) -{ - fprintf(stderr, "Usage is : %s [c|d] <codepage> <inputfile> <outputfile>\n", - progname); - exit(1); -} - -/* - * Read a line from a buffer into a line buffer. Ensure null - * terminated. - */ - -void read_line( char **buf, char *line_buf, int size) -{ - char *p = *buf; - int num = 0; - - for(; *p && (*p != '\n'); p++) - { - if(num < (size - 1)) - line_buf[num++] = *p; - } - if(*p) - p++; /* Go past the '\n' */ - line_buf[num] = '\0'; - *buf = p; -} - -/* - * Strip comment lines and blank lines from the data. - * Copies into a new buffer and frees the old. - * Returns the number of lines copied. - */ - -int clean_data( char **buf, uint32 *size) -{ - char linebuf[512]; - char *p = *buf; - int num_lines = 0; - char *newbuf = (char *)malloc( *size + 1); - char *newbuf_p = NULL; - - if(newbuf == NULL) - { - fprintf(stderr, "%s: malloc fail for size %d.\n", prog_name, *size + 1); - exit(1); - } - - newbuf_p = newbuf; - *newbuf_p = '\0'; - - while( *p ) - { - char *cp; - - read_line( &p, linebuf, sizeof(linebuf)); - /* Null terminate after comment. */ - if((cp = strchr( linebuf, '#'))!= NULL) - *cp = '\0'; - - for(cp = linebuf;*cp && isspace(*cp); cp++) - ; - - if(*cp == '\0') - continue; - - strcpy(newbuf_p, cp); - num_lines++; - newbuf_p += (strlen(newbuf_p) + 1); - } - - free(*buf); - *buf = newbuf; - return num_lines; -} - -/* - * Parse a byte from a codepage file. - */ - -BOOL parse_byte(char *buf, unsigned char *bp) -{ - unsigned int b; - char *endptr = NULL; - - b = (unsigned int)strtol(buf, &endptr, 0); - if(endptr == buf || b > 255) - return False; - - *bp = (unsigned char)b; - return True; -} - -/* - * Parse a bool from a codepage file. - */ - -BOOL parse_bool(char *buf, unsigned char *bp) -{ - if(isdigit(*buf)) - { - char *endptr = NULL; - - *bp = (unsigned char)strtol(buf, &endptr, 0); - if(endptr == buf ) - return False; - if(*bp != 0) - *bp = 1; - } else { - if(strcasecmp(buf, "True") && strcasecmp(buf, "False")) - return False; - if(strcasecmp(buf, "True")==0) - *bp = 1; - else - *bp = 0; - } - return True; -} - -/* - * Print a parse error and exit. - */ - -void parse_error(char *buf, char *msg) -{ - fprintf(stderr, "%s: %s whilst parsing line \n%s\n", prog_name, - msg, buf); - exit(1); -} - -/* - * Create a compiled codepage file from a codepage definition file. - */ - -int do_compile(int codepage, char *input_file, char *output_file) -{ - FILE *fp = NULL; - uint32 size = 0; - char *buf = NULL; - char output_buf[CODEPAGE_HEADER_SIZE + 512]; - int num_lines = 0; - int i = 0; - struct stat st; - - /* Get the size of the input file. Read the entire thing into memory. */ - if(stat((char *)input_file, &st)!= 0) - { - fprintf(stderr, "%s: failed to get the file size for file %s. Error was %s\n", - prog_name, input_file, strerror(errno)); - exit(1); - } - - size = (uint32)st.st_size; - - /* I don't believe these things should be bigger than 100k :-) */ - if(size > 100*1024) - { - fprintf(stderr, "%s: filesize %d is too large for a codepage definition file. \ -The maximum size I will believe is 100k.\n", prog_name, size); - exit(1); - } - - if((fp = fopen(input_file, "r")) == NULL) - { - fprintf(stderr, "%s: cannot open file %s for input.\n", prog_name, input_file); - exit(1); - } - - /* As we will be reading text, allocate one more byte for a '\0' */ - if((buf = (char *)malloc( size + 1 )) == NULL) - { - fprintf(stderr, "%s: malloc fail for size %d.\n", prog_name, size + 1); - fclose(fp); - exit(1); - } - - if(fread( buf, 1, size, fp) != size) - { - fprintf(stderr, "%s: read failed for file %s. Error was %s.\n", prog_name, - input_file, strerror(errno)); - free((char *)buf); - fclose(fp); - exit(1); - } - - /* Null terminate the text read. */ - buf[size] = '\0'; - - /* Go through the data line by line, strip out comments (anything - after a '#' to end-of-line) and blank lines. The rest should be - the codepage data. - */ - - num_lines = clean_data( &buf, &size); - - /* There can be a maximum of 128 lines. */ - if(num_lines > 128) - { - fprintf(stderr, "%s: There can be a maximum 128 lines of data in a codepage \ -definition file. File %s has %d.\n", prog_name, input_file, num_lines); - exit(1); - } - - /* Setup the output file header. */ - SSVAL(output_buf,CODEPAGE_VERSION_OFFSET,CODEPAGE_FILE_VERSION_ID); - SSVAL(output_buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET,(uint16)codepage); - SIVAL(output_buf,CODEPAGE_LENGTH_OFFSET,(num_lines * 4)); - - /* Now convert the lines into the compiled form. */ - for(i = 0; i < num_lines; i++) - { - char token_buf[512]; - char *p = buf; - unsigned char b = 0; - - /* Get the 'lower' value. */ - if(!next_token(&p, token_buf, NULL)) - parse_error(buf, "cannot parse first value"); - if(!parse_byte( token_buf, &b)) - parse_error(buf, "first value doesn't resolve to a byte"); - - /* Add this to the output buffer. */ - SCVAL(output_buf,CODEPAGE_HEADER_SIZE+(i*4),b); - - /* Get the 'upper' value. */ - if(!next_token(&p, token_buf, NULL)) - parse_error(buf, "cannot parse second value"); - if(!parse_byte( token_buf, &b)) - parse_error(buf, "second value doesn't resolve to a byte"); - - /* Add this to the output buffer. */ - SCVAL(output_buf,CODEPAGE_HEADER_SIZE+(i*4) + 1,b); - - /* Get the 'upper to lower' value. */ - if(!next_token(&p, token_buf, NULL)) - parse_error(buf, "cannot parse third value"); - if(!parse_bool( token_buf, &b)) - parse_error(buf, "third value doesn't resolve to a boolean"); - - /* Add this to the output buffer. */ - SCVAL(output_buf,CODEPAGE_HEADER_SIZE+(i*4) + 2,b); - - /* Get the 'lower to upper' value. */ - if(!next_token(&p, token_buf, NULL)) - parse_error(buf, "cannot parse fourth value"); - if(!parse_bool( token_buf, &b)) - parse_error(buf, "fourth value doesn't resolve to a boolean"); - - /* Add this to the output buffer. */ - SCVAL(output_buf,CODEPAGE_HEADER_SIZE+(i*4) + 3,b); - - buf += (strlen(buf) + 1); - } - - /* Now write out the output_buf. */ - if((fp = fopen(output_file, "w"))==NULL) - { - fprintf(stderr, "%s: Cannot open output file %s. Error was %s.\n", - prog_name, output_file, strerror(errno)); - exit(1); - } - - if(fwrite(output_buf, 1, CODEPAGE_HEADER_SIZE + (num_lines*4), fp) != - CODEPAGE_HEADER_SIZE + (num_lines*4)) - { - fprintf(stderr, "%s: Cannot write output file %s. Error was %s.\n", - prog_name, output_file, strerror(errno)); - exit(1); - } - - fclose(fp); - - return 0; -} - -/* - * Placeholder for now. - */ - -int do_decompile( int codepage, char *input_file, char *output_file) -{ - uint32 size = 0; - struct stat st; - char header_buf[CODEPAGE_HEADER_SIZE]; - char *buf = NULL; - FILE *fp = NULL; - int num_lines = 0; - int i = 0; - - /* Get the size of the input file. Read the entire thing into memory. */ - if(stat((char *)input_file, &st)!= 0) - { - fprintf(stderr, "%s: failed to get the file size for file %s. Error was %s\n", - prog_name, input_file, strerror(errno)); - exit(1); - } - - size = (uint32)st.st_size; - - if( size < CODEPAGE_HEADER_SIZE || size > (CODEPAGE_HEADER_SIZE + 256)) - { - fprintf(stderr, "%s: file %s is an incorrect size for a \ -code page file.\n", prog_name, input_file); - exit(1); - } - - /* Read the first 8 bytes of the codepage file - check - the version number and code page number. All the data - is held in little endian format. - */ - - if((fp = fopen( input_file, "r")) == NULL) - { - fprintf(stderr, "%s: cannot open file %s. Error was %s\n", - prog_name, input_file, strerror(errno)); - exit(1); - } - - if(fread( header_buf, 1, CODEPAGE_HEADER_SIZE, fp)!=CODEPAGE_HEADER_SIZE) - { - fprintf(stderr, "%s: cannot read header from file %s. Error was %s\n", - prog_name, input_file, strerror(errno)); - exit(1); - } - - /* Check the version value */ - if(SVAL(header_buf,CODEPAGE_VERSION_OFFSET) != CODEPAGE_FILE_VERSION_ID) - { - fprintf(stderr, "%s: filename %s has incorrect version id. \ -Needed %hu, got %hu.\n", - prog_name, input_file, (uint16)CODEPAGE_FILE_VERSION_ID, - SVAL(header_buf,CODEPAGE_VERSION_OFFSET)); - exit(1); - } - - /* Check the codepage matches */ - if(SVAL(header_buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET) != (uint16)codepage) - { - fprintf(stderr, "%s: filename %s has incorrect codepage. \ -Needed %hu, got %hu.\n", - prog_name, input_file, (uint16)codepage, - SVAL(header_buf,CODEPAGE_CLIENT_CODEPAGE_OFFSET)); - exit(1); - } - - /* Check the length is correct. */ - if(IVAL(header_buf,CODEPAGE_LENGTH_OFFSET) != - (unsigned int)(size - CODEPAGE_HEADER_SIZE)) - { - fprintf(stderr, "%s: filename %s has incorrect size headers. \ -Needed %u, got %u.\n", prog_name, input_file, size - CODEPAGE_HEADER_SIZE, - IVAL(header_buf,CODEPAGE_LENGTH_OFFSET)); - exit(1); - } - - size -= CODEPAGE_HEADER_SIZE; /* Remove header */ - - /* Make sure the size is a multiple of 4. */ - if((size % 4 ) != 0) - { - fprintf(stderr, "%s: filename %s has a codepage size not a \ -multiple of 4.\n", prog_name, input_file); - exit(1); - } - - /* Allocate space for the code page file and read it all in. */ - if((buf = (char *)malloc( size )) == NULL) - { - fprintf (stderr, "%s: malloc fail for size %d.\n", - prog_name, size ); - exit(1); - } - - if(fread( buf, 1, size, fp)!=size) - { - fprintf(stderr, "%s: read fail on file %s. Error was %s.\n", - prog_name, input_file, strerror(errno)); - exit(1); - } - - fclose(fp); - - /* Now dump the codepage into an ascii file. */ - if((fp = fopen(output_file, "w")) == NULL) - { - fprintf(stderr, "%s: cannot open file %s. Error was %s\n", - prog_name, output_file, strerror(errno)); - exit(1); - } - - fprintf(fp, "#\n# Codepage definition file for IBM Code Page %d.\n#\n", - codepage); - fprintf(fp, "# This file was automatically generated.\n#\n"); - fprintf(fp, "# defines lower->upper mapping.\n"); - fprintf(fp, "#\n#The columns are :\n# lower\tupper\tu-t-l\tl-t-u\n#\n"); - - num_lines = size / 4; - for( i = 0; i < num_lines; i++) - { - fprintf(fp, "0x%02X\t0x%02X\t%s\t%s\n", CVAL(buf, (i*4)), CVAL(buf, (i*4)+1), - CVAL(buf, (i*4)+2) ? "True" : "False", - CVAL(buf, (i*4)+3) ? "True" : "False"); - } - fclose(fp); - return 0; -} - -int main(int argc, char **argv) -{ - int codepage = 0; - char *input_file = NULL; - char *output_file = NULL; - BOOL compile = False; - - prog_name = argv[0]; - - if(argc != 5) - codepage_usage(prog_name); - - if(argv[1][0] != 'c' && argv[1][0] != 'C' && argv[1][0] != 'd' && - argv[1][0] != 'D') - codepage_usage(prog_name); - - input_file = argv[3]; - output_file = argv[4]; - - /* Are we compiling or decompiling. */ - if(argv[1][0] == 'c' || argv[1][0] == 'C') - compile = True; - - /* Convert the second argument into a client codepage value. */ - if((codepage = atoi(argv[2])) == 0) - { - fprintf(stderr, "%s: %s is not a valid codepage.\n", prog_name, argv[2]); - exit(1); - } - - if(compile) - return do_compile( codepage, input_file, output_file); - else - return do_decompile( codepage, input_file, output_file); -} diff --git a/source/utils/nmblookup.c b/source/utils/nmblookup.c index 36905aa5ae3..aebbc4292ca 100644 --- a/source/utils/nmblookup.c +++ b/source/utils/nmblookup.c @@ -35,8 +35,6 @@ extern struct in_addr ipzero; int ServerFD= -1; -int RootPort = 0; - /**************************************************************************** open the socket communication **************************************************************************/ @@ -51,10 +49,7 @@ static BOOL open_sockets(void) return False; } - ServerFD = open_socket_in( SOCK_DGRAM, - (RootPort ? 137 :0), - 3, - interpret_addr(lp_socket_address()) ); + ServerFD = open_socket_in(SOCK_DGRAM, 0,3,interpret_addr(lp_socket_address())); if (ServerFD == -1) return(False); @@ -118,7 +113,7 @@ int main(int argc,char *argv[]) charset_initialise(); - while ((opt = getopt(argc, argv, "d:B:i:s:SMrh")) != EOF) + while ((opt = getopt(argc, argv, "p:d:B:i:s:SMh")) != EOF) switch (opt) { case 'B': @@ -142,9 +137,6 @@ int main(int argc,char *argv[]) case 's': pstrcpy(servicesf, optarg); break; - case 'r': - RootPort = -1; - break; case 'h': usage(); exit(0); diff --git a/source/utils/smbpasswd.c b/source/utils/smbpasswd.c index d20ff42c0e8..161555d52cc 100644 --- a/source/utils/smbpasswd.c +++ b/source/utils/smbpasswd.c @@ -1,3 +1,5 @@ +#ifdef SMB_PASSWD + /* * Unix SMB/Netbios implementation. Version 1.9. smbpasswd module. Copyright * (C) Jeremy Allison 1995-1997. @@ -18,6 +20,7 @@ */ #include "includes.h" +#include "des.h" /* Static buffers we will return. */ static struct smb_passwd pw_buf; @@ -375,24 +378,14 @@ static void usage(char *name) * Open the smbpaswd file XXXX - we need to parse smb.conf to get the * filename */ - fp = fopen(pfile, "r+"); - if (!fp && errno == ENOENT) { - fp = fopen(pfile, "w"); - if (fp) { - fprintf(fp, "# Samba SMB password file\n"); - fclose(fp); - fp = fopen(pfile, "r+"); - } - } - if (!fp) { - err = errno; - fprintf(stderr, "%s: Failed to open password file %s.\n", - argv[0], pfile); - errno = err; - perror(argv[0]); - exit(err); + if ((fp = fopen(pfile, "r+")) == NULL) { + err = errno; + fprintf(stderr, "%s: Failed to open password file %s.\n", + argv[0], pfile); + errno = err; + perror(argv[0]); + exit(err); } - /* Set read buffer to 16k for effiecient reads */ setvbuf(fp, readbuf, _IOFBF, sizeof(readbuf)); @@ -424,8 +417,10 @@ static void usage(char *name) /* Create a new smb passwd entry and set it to the given password. */ { int fd; + int i; int new_entry_length; char *new_entry; + char *p; long offpos; /* The add user write needs to be atomic - so get the fd from @@ -435,7 +430,7 @@ static void usage(char *name) if((offpos = lseek(fd, 0, SEEK_END)) == -1) { fprintf(stderr, "%s: Failed to add entry for user %s to file %s. \ -Error was %s\n", argv[0], pwd->pw_name, pfile, strerror(errno)); +Error was %d\n", argv[0], pwd->pw_name, pfile, errno); fclose(fp); pw_file_unlock(lockfd); exit(1); @@ -447,7 +442,7 @@ Error was %s\n", argv[0], pwd->pw_name, pfile, strerror(errno)); strlen(pwd->pw_shell) + 1; if((new_entry = (char *)malloc( new_entry_length )) == 0) { fprintf(stderr, "%s: Failed to add entry for user %s to file %s. \ -Error was %s\n", argv[0], pwd->pw_name, pfile, strerror(errno)); +Error was %d\n", argv[0], pwd->pw_name, pfile, errno); fclose(fp); pw_file_unlock(lockfd); exit(1); @@ -467,12 +462,12 @@ Error was %s\n", argv[0], pwd->pw_name, pfile, strerror(errno)); pwd->pw_dir, pwd->pw_shell); if(write(fd, new_entry, strlen(new_entry)) != strlen(new_entry)) { fprintf(stderr, "%s: Failed to add entry for user %s to file %s. \ -Error was %s\n", argv[0], pwd->pw_name, pfile, strerror(errno)); +Error was %d\n", argv[0], pwd->pw_name, pfile, errno); /* Remove the entry we just wrote. */ if(ftruncate(fd, offpos) == -1) { fprintf(stderr, "%s: ERROR failed to ftruncate file %s. \ -Error was %s. Password file may be corrupt ! Please examine by hand !\n", - argv[0], pwd->pw_name, strerror(errno)); +Error was %d. Password file may be corrupt ! Please examine by hand !\n", + argv[0], pwd->pw_name, errno); } fclose(fp); pw_file_unlock(lockfd); @@ -483,9 +478,6 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n", pw_file_unlock(lockfd); exit(0); } - } else { - /* the entry already existed */ - add_user = False; } /* If we are root or the password is 'NO PASSWORD' then @@ -579,3 +571,14 @@ Error was %s. Password file may be corrupt ! Please examine by hand !\n", return 0; } +#else + +#include "includes.h" + +int +main(int argc, char **argv) +{ + printf("smb password encryption not selected in Makefile\n"); + return 0; +} +#endif diff --git a/source/utils/status.c b/source/utils/status.c index 703105012ef..6fa85c0a630 100644 --- a/source/utils/status.c +++ b/source/utils/status.c @@ -98,10 +98,10 @@ for share file %s (%s)\n", progname, fname, strerror(errno)); return 0; } - if (IVAL(buf,SMF_VERSION_OFFSET) != LOCKING_VERSION) { + if (IVAL(buf,0) != LOCKING_VERSION) { printf("%s: ERROR: read_share_file: share file %s has incorrect \ locking version (was %d, should be %d).\n",fname, - progname, IVAL(buf,SMF_VERSION_OFFSET), LOCKING_VERSION); + progname, IVAL(buf,0), LOCKING_VERSION); if(buf) free(buf); return 0; @@ -109,13 +109,13 @@ locking version (was %d, should be %d).\n",fname, /* Sanity check for file contents */ size = sb.st_size; - size -= SMF_HEADER_LENGTH; /* Remove the header */ + size -= 10; /* Remove the header */ /* Remove the filename component. */ - size -= SVAL(buf, SMF_FILENAME_LEN_OFFSET); + size -= SVAL(buf, 8); - /* The remaining size must be a multiple of SMF_ENTRY_LENGTH - error if not. */ - if((size % SMF_ENTRY_LENGTH) != 0) + /* The remaining size must be a multiple of 16 - error if not. */ + if((size % 16) != 0) { printf("%s: ERROR: read_share_file: share file %s is an incorrect length.\n", progname, fname); @@ -148,9 +148,6 @@ locking version (was %d, should be %d).\n",fname, void *dir; char *s; #endif /* FAST_SHARE_MODES */ -#ifdef USE_OPLOCKS - int oplock_type; -#endif /* USE_OPLOCKS */ int i; struct session_record *ptr; @@ -347,10 +344,6 @@ locking version (was %d, should be %d).\n",fname, t.tv_sec = entry_scanner_p->time.tv_sec; t.tv_usec = entry_scanner_p->time.tv_usec; strcpy(fname, file_scanner_p->file_name); -#ifdef USE_OPLOCKS - oplock_type = entry_scanner_p->op_type; -#endif /* USE_OPLOCKS */ - #else /* FAST_SHARE_MODES */ /* For slow share modes go through all the files in @@ -401,19 +394,16 @@ locking version (was %d, should be %d).\n",fname, strcpy( fname, &buf[10]); close(fd); - base = buf + SMF_HEADER_LENGTH + SVAL(buf,SMF_FILENAME_LEN_OFFSET); - for( i = 0; i < IVAL(buf, SMF_NUM_ENTRIES_OFFSET); i++) + base = buf + 10 + SVAL(buf,8); + for( i = 0; i < IVAL(buf, 4); i++) { - char *p = base + (i*SMF_ENTRY_LENGTH); + char *p = base + (i*16); struct timeval t; - int pid = IVAL(p,SME_PID_OFFSET); - int mode = IVAL(p,SME_SHAREMODE_OFFSET); + int pid = IVAL(p,12); + int mode = IVAL(p,8); - t.tv_sec = IVAL(p,SME_SEC_OFFSET); - t.tv_usec = IVAL(p,SME_USEC_OFFSET); -#ifdef USE_OPLOCKS - oplock_type = SVAL(p,SME_OPLOCK_TYPE_OFFSET); -#endif /* USE_OPLOCKS */ + t.tv_sec = IVAL(p,0); + t.tv_usec = IVAL(p,4); #endif /* FAST_SHARE_MODES */ fname[sizeof(fname)-1] = 0; @@ -421,13 +411,8 @@ locking version (was %d, should be %d).\n",fname, if (firstopen) { firstopen=False; printf("Locked files:\n"); -#ifdef USE_OPLOCKS - printf("Pid DenyMode R/W Oplock Name\n"); - printf("--------------------------------------------------\n"); -#else /* USE_OPLOCKS */ - printf("Pid DenyMode R/W Name\n"); - printf("----------------------------------\n"); -#endif /* USE_OPLOCKS */ + printf("Pid DenyMode R/W Name\n"); + printf("------------------------------\n"); } @@ -442,20 +427,10 @@ locking version (was %d, should be %d).\n",fname, } switch (mode&0xF) { - case 0: printf("RDONLY "); break; - case 1: printf("WRONLY "); break; - case 2: printf("RDWR "); break; + case 0: printf("RDONLY "); break; + case 1: printf("WRONLY "); break; + case 2: printf("RDWR "); break; } -#ifdef USE_OPLOCKS - if((oplock_type & (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) == (EXCLUSIVE_OPLOCK|BATCH_OPLOCK)) - printf("EXCLUSIVE+BATCH "); - else if (oplock_type & EXCLUSIVE_OPLOCK) - printf("EXCLUSIVE "); - else if (oplock_type & BATCH_OPLOCK) - printf("BATCH "); - else - printf("NONE "); -#endif /* USE_OPLOCKS */ printf(" %s %s",fname,asctime(LocalTime((time_t *)&t.tv_sec))); #ifdef FAST_SHARE_MODES diff --git a/source/utils/testparm.c b/source/utils/testparm.c index ca364cb8c94..81e69cd76fb 100644 --- a/source/utils/testparm.c +++ b/source/utils/testparm.c @@ -82,7 +82,7 @@ extern int DEBUGLEVEL; printf("Press enter to see a dump of your service definitions\n"); fflush(stdout); getc(stdin); - lp_dump(stdout); + lp_dump(); } if (argc == 4) diff --git a/source/web/cgi.c b/source/web/cgi.c deleted file mode 100644 index 56c293985d6..00000000000 --- a/source/web/cgi.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - some simple CGI helper routines - Copyright (C) Andrew Tridgell 1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - - -#include "includes.h" - -#define MAX_VARIABLES 512 - -struct var { - char *name; - char *value; -}; - -static struct var variables[MAX_VARIABLES]; -static int num_variables; - - -static int grab_line(int *cl, char *line, int maxsize) -{ - int i = 0; - - while ((*cl)) { - int c = fgetc(stdin); - (*cl)--; - - if (c == EOF) { - (*cl) = 0; - break; - } - - if (c == '+') { - c = ' '; - } - - if (c == '\r') continue; - - if (strchr("\n&", c)) break; - - if (c == '%' && (*cl) >= 2) { - int c1, c2; - c1 = fgetc(stdin); - c2 = fgetc(stdin); - (*cl) -= 2; - if (c1 == EOF || c2 == EOF) break; - if (c1 >= '0' && c1 <= '9') - c1 = c1 - '0'; - else if (c1 >= 'A' && c1 <= 'F') - c1 = 10 + c1 - 'A'; - else if (c1 >= 'a' && c1 <= 'f') - c1 = 10 + c1 - 'a'; - else break; - - if (c2 >= '0' && c2 <= '9') - c2 = c2 - '0'; - else if (c2 >= 'A' && c2 <= 'F') - c2 = 10 + c2 - 'A'; - else if (c2 >= 'a' && c2 <= 'f') - c2 = 10 + c2 - 'a'; - else break; - - c = (c1<<4) | c2; - } - - line[i++] = c; - - if (i == maxsize) break; - } - - /* now unescape the line */ - - - line[i] = 0; - return 1; -} - - -/*************************************************************************** - load all the variables passed to the CGI program - ***************************************************************************/ -void cgi_load_variables(void) -{ - static pstring line; - char *p; - int len; - - if (!(p=getenv("CONTENT_LENGTH"))) return; - - len = atoi(p); - - if (len <= 0) return; - - - - while (len && grab_line(&len, line, sizeof(line)-1)) { - p = strchr(line,'='); - if (!p) continue; - - *p = 0; - - variables[num_variables].name = strdup(line); - variables[num_variables].value = strdup(p+1); - - if (!variables[num_variables].name || - !variables[num_variables].value) - continue; - -#if 0 - printf("%s=%s<br>\n", - variables[num_variables].name, - variables[num_variables].value); -#endif - - num_variables++; - if (num_variables == MAX_VARIABLES) break; - } - - fclose(stdin); -} - - -/*************************************************************************** - find a variable passed via CGI - ***************************************************************************/ -char *cgi_variable(char *name) -{ - int i; - - for (i=0;i<num_variables;i++) - if (strcmp(variables[i].name, name) == 0) - return variables[i].value; - return NULL; -} - - -/*************************************************************************** - return the value of a CGI boolean variable. - ***************************************************************************/ -int cgi_boolean(char *name, int def) -{ - char *p = cgi_variable(name); - - if (!p) return def; - - return strcmp(p, "1") == 0; -} diff --git a/source/wsmbconf.c b/source/wsmbconf.c deleted file mode 100644 index 203952c204f..00000000000 --- a/source/wsmbconf.c +++ /dev/null @@ -1,251 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - html smb.conf editing - prototype only - Copyright (C) Andrew Tridgell 1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifdef SYSLOG -#undef SYSLOG -#endif - -#include "includes.h" -#include "smb.h" - -#define SDEFAULTS "Service defaults" -#define SGLOBAL "Global Parameters" -#define GLOBALS_SNUM -2 -#define DEFAULTS_SNUM -1 - - -/* start the page with standard stuff */ -static void print_header(void) -{ - printf("Content-type: text/html\n\n"); - printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2//EN\">\n"); - printf("<HTML>\n<HEAD>\n<TITLE>smb.conf</TITLE>\n</HEAD>\n<BODY>\n\n"); -} - - -/* finish off the page */ -static void print_footer(void) -{ - printf("\n</BODY>\n</HTML>\n"); -} - -/* setup persisant variables */ -static void set_persistent(char *name) -{ - char *p; - p = cgi_variable(name); - if (!p) return; - printf("<input type=hidden name=%s value=%s>\n", name, p); -} - -/* display a servce, ready for editing */ -static void show_service(int snum, int allparameters) -{ - int i = 0; - pstring label, value; - char *sname; - - if (snum == GLOBALS_SNUM) - sname = SGLOBAL; - else if (snum == DEFAULTS_SNUM) - sname = SDEFAULTS; - else sname = lp_servicename(snum); - - printf("\n<p><table border=0>\n<tr>\n<td></td><td>\n\n"); - printf("<form method=POST>\n"); - printf("<H3>%s</H3>\n", sname); - printf("<input type=hidden name=service value=\"%s\">\n", sname); - printf("<input type=submit name=request value=Change>\n"); - printf("<input type=submit name=request value=Rename>\n"); - printf("<input type=submit name=request value=Copy>\n"); - printf("<input type=submit name=request value=Remove>\n"); - printf("<br><input name=newvalue><br>\n"); - printf("<select name=parameter size=5>\n"); - - while (lp_next_parameter(snum, &i, label, value, allparameters)) { - printf("<option value=\"%s\">%s = %s\n", - label, label, value); - } - - printf("</select>\n"); - printf("</form>\n</td>\n</tr>\n</table>\n"); - - printf("<p>\n"); -} - - -/* loop over all services, displaying them one after the other */ -static void show_services(void) -{ - int i; - int n; - int allparameters = cgi_boolean("allparameters", 0); - - printf("<FORM METHOD=POST>\n"); - printf("<p>Show all parameters?\n"); - printf("<INPUT NAME=allparameters TYPE=checkbox VALUE=1 %s>\n", - allparameters?"CHECKED":""); - - printf("<INPUT TYPE=submit NAME=reload VALUE=Reload>\n"); - - printf("</FORM>\n"); - - n = lp_numservices(); - - show_service(GLOBALS_SNUM, allparameters); - show_service(DEFAULTS_SNUM, allparameters); - - for (i=0;i<n;i++) - if (VALID_SNUM(i)) - show_service(i, allparameters); -} - - -/* load the smb.conf file into loadparm. this also does the chroot - to the config directory. This must be called _BEFORE_ any client - supplied data is parsed */ -static int load_config(void) -{ - static pstring servicesf = CONFIGFILE; - char *p; - - p = strrchr(servicesf,'/'); - if (!p) return 0; - - *p = 0; - - setuid(0); - - if (chdir(servicesf) || chroot(servicesf)) { - printf("wsmbconf is not configured correctly\n"); - return 0; - } - - *p = '/'; - - if (!lp_load(p,False)) { - printf("<b>Can't load %s - using defaults</b><p>\n", - servicesf); - } - return 1; -} - - -static int save_reload(void) -{ - static pstring servicesf = CONFIGFILE; - char *p; - FILE *f; - - p = strrchr(servicesf,'/'); - if (!p) return 0; - - f = fopen(p,"w"); - if (!f) { - printf("failed to open %s for writing\n", servicesf); - return 0; - } - - fprintf(f, "# Samba config file created using wsmbconf\n"); - - lp_dump(f); - - fclose(f); - - lp_killunused(NULL); - - if (!lp_load(p,False)) { - printf("Can't reload %s\n", servicesf); - return 0; - } - - return 1; -} - -static void process_requests(void) -{ - char *req = cgi_variable("request"); - char *newvalue = cgi_variable("newvalue"); - char *parameter = cgi_variable("parameter"); - char *service = cgi_variable("service"); - int snum=0; - - if (!req) return; - - if (service) { - /* work out what service it is */ - if (strcmp(service,SGLOBAL) == 0) { - snum = GLOBALS_SNUM; - } else if (strcmp(service,SDEFAULTS) == 0) { - snum = DEFAULTS_SNUM; - } else { - snum = lp_servicenumber(service); - if (snum < 0) return; - } - } - - if (!newvalue) - newvalue = ""; - - if (strcmp(req,"Change") == 0) { - /* change the value of a parameter */ - if (!parameter || !service) return; - - lp_do_parameter(snum, parameter, newvalue); - } else if (strcmp(req,"Rename") == 0) { - /* rename a service */ - if (!newvalue || !service) return; - - lp_rename_service(snum, newvalue); - } else if (strcmp(req,"Remove") == 0) { - /* remove a service */ - if (!service) return; - - lp_remove_service(snum); - } else if (strcmp(req,"Copy") == 0) { - /* copy a service */ - if (!service || !newvalue) return; - - lp_copy_service(snum, newvalue); - } - - save_reload(); -} - - -int main(int argc, char *argv[]) -{ - extern FILE *dbf; - - print_header(); - - dbf = stderr; - - charset_initialise(); - - if (load_config()) { - cgi_load_variables(); - process_requests(); - show_services(); - } - print_footer(); - return 0; -} diff --git a/source/wsmbstatus.c b/source/wsmbstatus.c deleted file mode 100644 index 2762b8610e7..00000000000 --- a/source/wsmbstatus.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - html status reporting - Copyright (C) Andrew Tridgell 1997 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#ifdef SYSLOG -#undef SYSLOG -#endif - -#include "includes.h" - -static void print_header(void) -{ - printf("Content-type: text/html\n\n"); - printf("<HTML>\n<HEAD>\n<TITLE>smbstatus</TITLE>\n</HEAD>\n<BODY>\n\n"); -} - -static void print_footer(void) -{ - printf("\n</BODY>\n</HTML>\n"); -} - -static void show_connections(void) -{ - static pstring servicesf = CONFIGFILE; - pstring fname; - FILE *f; - struct connect_record crec; - - if (!lp_load(servicesf,False)) { - printf("Can't load %s - run testparm to debug it\n", servicesf); - return; - } - - strcpy(fname,lp_lockdir()); - standard_sub_basic(fname); - trim_string(fname,"","/"); - strcat(fname,"/STATUS..LCK"); - - f = fopen(fname,"r"); - if (!f) { - printf("Couldn't open status file %s\n",fname); - if (!lp_status(-1)) - printf("You need to have status=yes in your smb config file\n"); - return; - } - - - printf("\nSamba version %s\n<p>",VERSION); - - while (!feof(f)) { - if (fread(&crec,sizeof(crec),1,f) != 1) - break; - if (crec.magic == 0x280267 && process_exists(crec.pid)) { - printf("%-10.10s %-8s %-8s %5d %-8s (%s) %s<br>", - crec.name,uidtoname(crec.uid), - gidtoname(crec.gid),crec.pid, - crec.machine,crec.addr, - asctime(LocalTime(&crec.start))); - } - } - fclose(f); -} - -int main(int argc, char *argv[]) -{ - print_header(); - show_connections(); - print_footer(); - return 0; -} |