summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/proto.h4
-rw-r--r--source3/lib/util.c41
-rw-r--r--source3/param/loadparm.c154
-rw-r--r--source3/smbd/reply.c4
-rw-r--r--source3/smbd/server.c23
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);