Lines 1-230
Link Here
|
1 |
--- ./command.c.orig 2010-12-13 04:42:49.000000000 +0100 |
|
|
2 |
+++ ./command.c 2014-06-29 12:15:04.244544161 +0200 |
3 |
@@ -477,38 +477,90 @@ |
4 |
|
5 |
/* looks for special file info in transcripts */ |
6 |
char ** |
7 |
-special_t( char *transcript, char *epath ) |
8 |
+special_t( char *sp_path, char *remote_path ) |
9 |
{ |
10 |
- FILE *fs; |
11 |
- int ac, len; |
12 |
- char **av; |
13 |
+ FILE *fs = NULL; |
14 |
+ int i, ac, len, ln; |
15 |
+ char **av = NULL; |
16 |
+ char *paths[ 4 ] = { NULL }; |
17 |
+ char *p; |
18 |
+ char sp_t[ MAXPATHLEN ]; |
19 |
static char line[ MAXPATHLEN ]; |
20 |
|
21 |
- if (( fs = fopen( transcript, "r" )) == NULL ) { |
22 |
- return( NULL ); |
23 |
- } |
24 |
+ /* |
25 |
+ * in order, we look for special file transcript lines in the |
26 |
+ * following locations: |
27 |
+ * |
28 |
+ * - A transcript in the same directory and with the same name |
29 |
+ * as the special file, but with a ".T" extension. |
30 |
+ * |
31 |
+ * - A transcript named "<remote_id>.T" in the same directory as |
32 |
+ * the client's special file directory root. |
33 |
+ * |
34 |
+ * - /var/radmind/transcript/special.T |
35 |
+ * |
36 |
+ * if no matching transcript line is found, default metadata is |
37 |
+ * returned to the client (type: f; mode: 0444; owner: 0; group: 0). |
38 |
+ */ |
39 |
+ paths[ 0 ] = sp_path; |
40 |
+ paths[ 1 ] = special_dir; |
41 |
+ paths[ 2 ] = "transcript/special.T"; |
42 |
+ paths[ 3 ] = NULL; |
43 |
|
44 |
- while ( fgets( line, MAXPATHLEN, fs ) != NULL ) { |
45 |
- len = strlen( line ); |
46 |
- if (( line[ len - 1 ] ) != '\n' ) { |
47 |
- syslog( LOG_ERR, "special_t: %s: line too long", transcript ); |
48 |
- break; |
49 |
+ for ( i = 0; paths[ i ] != NULL; i++ ) { |
50 |
+ if (( p = strrchr( paths[ i ], '.' )) != NULL |
51 |
+ && strcmp( p, ".T" ) == 0 ) { |
52 |
+ if ( strlen( paths[ i ] ) >= MAXPATHLEN ) { |
53 |
+ syslog( LOG_WARNING, "special_t: path \"%s\" too long", |
54 |
+ paths[ i ] ); |
55 |
+ continue; |
56 |
+ } |
57 |
+ strcpy( sp_t, paths[ i ] ); |
58 |
+ } else if ( snprintf( sp_t, MAXPATHLEN, "%s.T", |
59 |
+ paths[ i ] ) >= MAXPATHLEN ) { |
60 |
+ syslog( LOG_WARNING, "special_t: path \"%s.T\" too long", sp_path ); |
61 |
+ continue; |
62 |
} |
63 |
|
64 |
- if (( ac = argcargv( line, &av )) != 8 ) { |
65 |
+ if (( fs = fopen( sp_t, "r" )) == NULL ) { |
66 |
continue; |
67 |
} |
68 |
- if (( *av[ 0 ] != 'f' ) && ( *av[ 0 ] != 'a' )) { |
69 |
- continue; |
70 |
+ |
71 |
+ ln = 0; |
72 |
+ while ( fgets( line, MAXPATHLEN, fs ) != NULL ) { |
73 |
+ ln++; |
74 |
+ len = strlen( line ); |
75 |
+ if (( line[ len - 1 ] ) != '\n' ) { |
76 |
+ syslog( LOG_ERR, "special_t: %s: line %d too long", sp_t, ln ); |
77 |
+ break; |
78 |
+ } |
79 |
+ |
80 |
+ /* only files and applefiles allowed */ |
81 |
+ if ( strncmp( line, "f ", strlen( "f " )) != 0 && |
82 |
+ strncmp( line, "a ", strlen( "a " )) != 0 ) { |
83 |
+ continue; |
84 |
+ } |
85 |
+ if (( ac = argcargv( line, &av )) != 8 ) { |
86 |
+ syslog( LOG_WARNING, "special_t: %s: line %d: " |
87 |
+ "bad transcript line", sp_t, ln ); |
88 |
+ continue; |
89 |
+ } |
90 |
+ |
91 |
+ if ( strcmp( av[ 1 ], remote_path ) == 0 ) { |
92 |
+ (void)fclose( fs ); |
93 |
+ return( av ); |
94 |
+ } |
95 |
} |
96 |
|
97 |
- if ( strcmp( av[ 1 ], epath ) == 0 ) { |
98 |
- (void)fclose( fs ); |
99 |
- return( av ); |
100 |
+ if ( fclose( fs ) != 0 ) { |
101 |
+ syslog( LOG_WARNING, "special_t: fclose %s: %m", sp_t ); |
102 |
} |
103 |
+ fs = NULL; |
104 |
} |
105 |
- |
106 |
- (void)fclose( fs ); |
107 |
+ if ( fs != NULL ) { |
108 |
+ (void)fclose( fs ); |
109 |
+ } |
110 |
+ |
111 |
return( NULL ); |
112 |
} |
113 |
|
114 |
@@ -624,11 +676,11 @@ |
115 |
switch ( key ) { |
116 |
case K_COMMAND: |
117 |
if ( ac == 2 ) { |
118 |
- snet_writef( sn, "%s %s %o %d %d %d %" PRIofft "d %s\r\n", |
119 |
+ snet_writef( sn, RADMIND_STAT_FMT, |
120 |
"f", "command", DEFAULT_MODE, DEFAULT_UID, DEFAULT_GID, |
121 |
st.st_mtime, st.st_size, cksum_b64 ); |
122 |
} else { |
123 |
- snet_writef( sn, "%s %s %o %d %d %d %" PRIofft "d %s\r\n", |
124 |
+ snet_writef( sn, RADMIND_STAT_FMT, |
125 |
"f", av[ 2 ], DEFAULT_MODE, DEFAULT_UID, DEFAULT_GID, |
126 |
st.st_mtime, st.st_size, cksum_b64 ); |
127 |
} |
128 |
@@ -636,61 +688,33 @@ |
129 |
|
130 |
|
131 |
case K_TRANSCRIPT: |
132 |
- snet_writef( sn, "%s %s %o %d %d %d %" PRIofft "d %s\r\n", |
133 |
+ snet_writef( sn, RADMIND_STAT_FMT, |
134 |
"f", av[ 2 ], |
135 |
DEFAULT_MODE, DEFAULT_UID, DEFAULT_GID, |
136 |
st.st_mtime, st.st_size, cksum_b64 ); |
137 |
return( 0 ); |
138 |
|
139 |
case K_SPECIAL: |
140 |
- /* status on a special file comes from 1 of three cases: |
141 |
- * 1. A transcript in the special file directory |
142 |
- * 2. A transcript in the Transcript dir with .T appended |
143 |
- * 3. No transcript is found, and constants are returned |
144 |
- */ |
145 |
- |
146 |
- /* look for transcript containing the information */ |
147 |
- if ( ( strlen( path ) + 2 ) > MAXPATHLEN ) { |
148 |
- syslog( LOG_WARNING, |
149 |
- "f_stat: transcript path longer than MAXPATHLEN" ); |
150 |
- |
151 |
- /* return constants */ |
152 |
- snet_writef( sn, "%s %s %o %d %d %d %" PRIofft "d %s\r\n", |
153 |
- "f", av[ 2 ], |
154 |
- DEFAULT_MODE, DEFAULT_UID, DEFAULT_GID, |
155 |
- st.st_mtime, st.st_size, cksum_b64 ); |
156 |
- return( 0 ); |
157 |
- } |
158 |
- |
159 |
- /* if allowable, check for transcript in the special file directory */ |
160 |
- |
161 |
- strcat( path, ".T" ); |
162 |
- |
163 |
- /* store value of av[ 2 ], because argcargv will be called |
164 |
+ /* |
165 |
+ * store value of av[ 2 ], because argcargv will be called |
166 |
* from special_t(), and that will blow away the current values |
167 |
- * for av[ 2 ] |
168 |
- * |
169 |
- * Could just use new argvargc API... XXX Notice how we never free |
170 |
- * env_file... |
171 |
+ * for av[ 2 ]. |
172 |
*/ |
173 |
- |
174 |
if (( enc_file = strdup( av[ 2 ] )) == NULL ) { |
175 |
syslog( LOG_ERR, "f_stat: strdup: %s %m", av[ 2 ] ); |
176 |
return( -1 ); |
177 |
} |
178 |
|
179 |
if (( av = special_t( path, enc_file )) == NULL ) { |
180 |
- if (( av = special_t( "transcript/special.T", enc_file )) |
181 |
- == NULL ) { |
182 |
- snet_writef( sn, "%s %s %o %d %d %d %" PRIofft "d %s\r\n", |
183 |
- "f", enc_file, |
184 |
- DEFAULT_MODE, DEFAULT_UID, DEFAULT_GID, |
185 |
- st.st_mtime, st.st_size, cksum_b64 ); |
186 |
- free( enc_file ); |
187 |
- return( 0 ); |
188 |
- } |
189 |
+ /* no special transcript match found, return defaults. */ |
190 |
+ snet_writef( sn, RADMIND_STAT_FMT, |
191 |
+ "f", enc_file, |
192 |
+ DEFAULT_MODE, DEFAULT_UID, DEFAULT_GID, |
193 |
+ st.st_mtime, st.st_size, cksum_b64 ); |
194 |
+ free( enc_file ); |
195 |
+ return( 0 ); |
196 |
} |
197 |
- snet_writef( sn, "%s %s %s %s %s %d %" PRIofft "d %s\r\n", |
198 |
+ snet_writef( sn, RADMIND_STAT_FMT, |
199 |
av[ 0 ], enc_file, |
200 |
av[ 2 ], av[ 3 ], av[ 4 ], |
201 |
st.st_mtime, st.st_size, cksum_b64 ); |
202 |
@@ -1261,8 +1285,7 @@ |
203 |
continue; |
204 |
} |
205 |
if ( strcmp( av[ 0 ], "@include" ) == 0 ) { |
206 |
- depth++; |
207 |
- if ( depth > RADMIND_MAX_INCLUDE_DEPTH ) { |
208 |
+ if ( depth >= RADMIND_MAX_INCLUDE_DEPTH ) { |
209 |
syslog( LOG_ERR, "%s: line %d: include %s exceeds max depth", |
210 |
path_config, linenum, av[ 1 ] ); |
211 |
goto command_k_done; |
212 |
@@ -1277,7 +1300,7 @@ |
213 |
continue; |
214 |
} |
215 |
} |
216 |
- if ( command_k( av[ 1 ], depth ) != 0 ) { |
217 |
+ if ( command_k( av[ 1 ], depth + 1 ) != 0 ) { |
218 |
continue; |
219 |
} |
220 |
|
221 |
@@ -1325,7 +1348,8 @@ |
222 |
|
223 |
/* If we get here, the host that connected is not in the config |
224 |
file. So screw him. */ |
225 |
- syslog( LOG_ERR, "host not in config file: %s", remote_host ); |
226 |
+ syslog( LOG_ERR, "host %s not in config file %s", |
227 |
+ remote_host, path_config ); |
228 |
|
229 |
command_k_done: |
230 |
snet_close( sn ); |