diff options
-rw-r--r-- | source3/include/proto.h | 4 | ||||
-rw-r--r-- | source3/lib/util.c | 41 | ||||
-rw-r--r-- | source3/param/loadparm.c | 154 | ||||
-rw-r--r-- | source3/smbd/reply.c | 4 | ||||
-rw-r--r-- | source3/smbd/server.c | 23 |
5 files changed, 174 insertions, 52 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index e4601672e0..d592c94634 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -183,6 +183,8 @@ int interpret_coding_system(char *str, int def); /*The following definitions come from loadparm.c */ +char *chomp(char *s); +char *read_string_external(char *fname); char *lp_string(char *s); char *lp_logfile(void); char *lp_smbrun(void); @@ -329,6 +331,7 @@ BOOL lp_syncalways(int ); BOOL lp_map_system(int ); BOOL lp_delete_readonly(int ); BOOL lp_fake_oplocks(int ); +BOOL lp_online(int ); BOOL lp_recursive_veto_delete(int ); BOOL lp_dos_filetimes(int ); int lp_create_mode(int ); @@ -1271,3 +1274,4 @@ char *align_offset(char *q, char *base, int align_offset_len); void print_asc(int level, unsigned char *buf,int len); void dump_data(int level,char *buf1,int len); char *tab_depth(int depth); +char *string_buffer(int sz); diff --git a/source3/lib/util.c b/source3/lib/util.c index 4d098013f2..9ee9bbab1c 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -4561,3 +4561,44 @@ char *tab_depth(int depth) } +/******************************************************************* +A convenience routine to grab string parameters into a rotating +buffer. The buffers can be written to by callers without affecting +the source string. +********************************************************************/ +char *string_buffer(int sz) +{ + static char *bufs[10]; + static int buflen[10]; + static int next = -1; + char *ret; + int i, len; + + if (next == -1) { + /* initialisation */ + for (i=0;i<10;i++) { + bufs[i] = NULL; + buflen[i] = 0; + } + next = 0; + } + + len = MAX(sz+100,sizeof(pstring)); /* the +100 is for some + substitution room */ + + if (buflen[next] != len) { + buflen[next] = len; + if (bufs[next]) free(bufs[next]); + bufs[next] = (char *)malloc(len); + if (!bufs[next]) { + DEBUG(0,("out of memory in lp_string_buffer()")); + exit(1); + } + } + + ret = &bufs[next][0]; + next = (next+1)%10; + *ret = 0; + + return(ret); +} diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 2fe616f709..a798444676 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -278,6 +278,7 @@ typedef struct BOOL *copymap; BOOL bDeleteReadonly; BOOL bFakeOplocks; + BOOL bOnline; BOOL bDeleteVetoFiles; BOOL bDosFiletimes; char dummy[3]; /* for alignment */ @@ -362,6 +363,7 @@ static service sDefault = NULL, /* copymap */ False, /* bDeleteReadonly */ False, /* bFakeOplocks */ + True, /* bOnline */ False, /* bDeleteVetoFiles */ False, /* bDosFiletimes */ "" /* dummy */ @@ -594,6 +596,7 @@ struct parm_struct {"magic output", P_STRING, P_LOCAL, &sDefault.szMagicOutput, NULL}, {"mangled map", P_STRING, P_LOCAL, &sDefault.szMangledMap, NULL}, {"delete readonly", P_BOOL, P_LOCAL, &sDefault.bDeleteReadonly, NULL}, + {"online", P_BOOL, P_LOCAL, &sDefault.bOnline, NULL}, {"dos filetimes", P_BOOL, P_LOCAL, &sDefault.bDosFiletimes, NULL}, {NULL, P_BOOL, P_NONE, NULL, NULL} @@ -772,57 +775,108 @@ static void init_locals(void) } -/******************************************************************* a -convenience routine to grab string parameters into a rotating buffer, -and run standard_sub_basic on them. The buffers can be written to by -callers without affecting the source string. -********************************************************************/ -char *lp_string(char *s) + +/* chomp() strips off trailing linefeed- and carriage-return-characters */ +char *chomp(char *s) { - static char *bufs[10]; - static int buflen[10]; - static int next = -1; - char *ret; - int i; - int len = s?strlen(s):0; + if(!s || s == NULL) +return(NULL); - if (next == -1) { - /* initialisation */ - for (i=0;i<10;i++) { - bufs[i] = NULL; - buflen[i] = 0; - } - next = 0; - } + while(strlen(s) > 0) { + int i = strlen(s) - 1; - len = MAX(len+100,sizeof(pstring)); /* the +100 is for some - substitution room */ + if(s [i] == '\n' || s [i] == '\r') + s [i] = '\0'; + else + break; + } - if (buflen[next] != len) { - buflen[next] = len; - if (bufs[next]) free(bufs[next]); - bufs[next] = (char *)malloc(len); - if (!bufs[next]) { - DEBUG(0,("out of memory in lp_string()")); - exit(1); - } - } + return(s); +} - ret = &bufs[next][0]; - next = (next+1)%10; - if (!s) - *ret = 0; - else - StrCpy(ret,s); +/* +read_string_external(fname): depending on the first character in fname either +reads the first line of a file or of the output of a command. If the second +character is a '$' execute standard-substitutions on the string to be returned. + +examples: read_string_external("</etc/HOSTNAME"); returns the hostname + read_string_external("|hostname"); returns the hostname too + read_string_external("<$/usr/local/samba/lib/your_hostname"); + returns the client-hostname, if + /.../your_hostname contains "%M" +*/ +char *read_string_external(char *fname) +{ + char *ret = NULL; + pstring str; + FILE *in = NULL; + int mode = 0, do_subst = 0, offset = 1; - trim_string(ret, "\"", "\""); + *str = '\0'; - standard_sub_basic(ret); - return(ret); + switch(*fname) { + case '<': mode = 0; break; + case '|': mode = 1; break; + default: return(NULL); break; + } + + if(*(fname + 1) == '$') { + do_subst = 1; + offset = 2; + } + + switch(mode) { + case 0: in = fopen(fname + offset, "r"); break; + case 1: in = popen(fname + offset, "r"); break; + } + + if(in != NULL) { + if(fgets(str, sizeof(str), in) == NULL) + *str = '\0'; + else + chomp(str); + + switch(mode) { + case 0: fclose(in); break; + case 1: pclose(in); break; + } + } + + if((ret = string_buffer(strlen(str)))) + { + StrCpy(ret, str); + + if(do_subst) + { + standard_sub_basic(ret); + } + } + + return(ret); } +char *lp_string(char *s) +{ + int len = s?strlen(s):0; + char *ret = NULL; + + if (!s) + *ret = 0; + else { + ret = string_buffer(len); + StrCpy(ret,s); + + standard_sub_basic(ret); + + if(*ret == '<' || *ret == '|') + ret = read_string_external(ret); + } + + return(ret); +} + /* In this section all the functions that are used to access the parameters from the rest of the program are defined @@ -997,6 +1051,7 @@ 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_online,bOnline) FN_LOCAL_BOOL(lp_recursive_veto_delete,bDeleteVetoFiles) FN_LOCAL_BOOL(lp_dos_filetimes,bDosFiletimes) @@ -2268,9 +2323,24 @@ int lp_servicenumber(char *pszServiceName) ******************************************************************/ char *volume_label(int snum) { + static char lbl [13]; char *ret = lp_volume(snum); - if (!*ret) return(lp_servicename(snum)); - return(ret); + int i = 0, j = 0; + + if (!*ret) + ret = lp_servicename(snum); + + lbl [0] = '\0'; + + while(*(ret + i) && j < sizeof(lbl) - 1) { + if(i == 8) + lbl [j++] = '.'; + + lbl [j++] = *(ret + i++); + lbl [j] = '\0'; + } + + return(lbl); } #if 0 diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 46425861d4..116542ba34 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1023,7 +1023,9 @@ int reply_search(char *inbuf,char *outbuf) if ((dirtype&0x1F) == aVOLID) { memcpy(p,status,21); - make_dir_struct(p,"???????????",volume_label(SNUM(cnum)),0,aVOLID,0); + mode = aVOLID; + if(!CAN_WRITE(cnum)) mode |= aRONLY; + make_dir_struct(p,"???????????",volume_label(SNUM(cnum)),0,mode,0); dptr_fill(p+12,dptr_num); if (dptr_zero(p+12) && (status_len==0)) numentries = 1; diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 095bc00e08..25d24eab53 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -4356,6 +4356,7 @@ force write permissions on print services. #define TIME_INIT (1<<2) #define CAN_IPC (1<<3) #define AS_GUEST (1<<5) +#define DONT_CHECK_ONLINE (1<<6) /* @@ -4377,15 +4378,15 @@ struct smb_message_struct /* CORE PROTOCOL */ - {SMBnegprot,"SMBnegprot",reply_negprot,0}, - {SMBtcon,"SMBtcon",reply_tcon,0}, - {SMBtdis,"SMBtdis",reply_tdis,0}, - {SMBexit,"SMBexit",reply_exit,0}, - {SMBioctl,"SMBioctl",reply_ioctl,0}, - {SMBecho,"SMBecho",reply_echo,0}, - {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,0}, - {SMBtconX,"SMBtconX",reply_tcon_and_X,0}, - {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */ + {SMBnegprot,"SMBnegprot",reply_negprot,DONT_CHECK_ONLINE}, + {SMBtcon,"SMBtcon",reply_tcon,DONT_CHECK_ONLINE}, + {SMBtdis,"SMBtdis",reply_tdis,DONT_CHECK_ONLINE}, + {SMBexit,"SMBexit",reply_exit,DONT_CHECK_ONLINE}, + {SMBioctl,"SMBioctl",reply_ioctl,DONT_CHECK_ONLINE}, + {SMBecho,"SMBecho",reply_echo,DONT_CHECK_ONLINE}, + {SMBsesssetupX,"SMBsesssetupX",reply_sesssetup_and_X,DONT_CHECK_ONLINE}, + {SMBtconX,"SMBtconX",reply_tcon_and_X,DONT_CHECK_ONLINE}, + {SMBulogoffX, "SMBulogoffX", reply_ulogoffX, DONT_CHECK_ONLINE}, /* ulogoff doesn't give a valid TID */ {SMBgetatr,"SMBgetatr",reply_getatr,AS_USER}, {SMBsetatr,"SMBsetatr",reply_setatr,AS_USER | NEED_WRITE}, {SMBchkpth,"SMBchkpth",reply_chkpth,AS_USER}, @@ -4575,6 +4576,10 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1))) return(ERROR(ERRSRV,ERRaccess)); + /* is this service online? */ + if (! (flags & DONT_CHECK_ONLINE) && ! lp_online(SNUM(cnum))) + return(ERROR(ERRHRD,ERRnotready)); + last_inbuf = inbuf; outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize); |