Changeset 732 for branches/samba-3.5.x/source3/libsmb/clifile.c
- Timestamp:
- Nov 12, 2012, 4:35:55 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/samba-3.5.x/source3/libsmb/clifile.c
r454 r732 2150 2150 2151 2151 struct cli_open_state { 2152 struct tevent_context *ev; 2153 struct cli_state *cli; 2154 const char *fname; 2152 2155 uint16_t vwv[15]; 2153 2156 uint16_t fnum; 2157 unsigned openfn; 2158 unsigned dos_deny; 2159 uint8_t additional_flags; 2154 2160 struct iovec bytes; 2155 2161 }; 2156 2162 2157 2163 static void cli_open_done(struct tevent_req *subreq); 2164 static void cli_open_ntcreate_done(struct tevent_req *subreq); 2158 2165 2159 2166 struct tevent_req *cli_open_create(TALLOC_CTX *mem_ctx, … … 2165 2172 struct tevent_req *req, *subreq; 2166 2173 struct cli_open_state *state; 2167 unsigned openfn;2168 unsigned accessmode;2169 uint8_t additional_flags;2170 2174 uint8_t *bytes; 2171 2175 … … 2174 2178 return NULL; 2175 2179 } 2176 2177 openfn = 0; 2180 state->ev = ev; 2181 state->cli = cli; 2182 state->fname = fname; 2183 2178 2184 if (flags & O_CREAT) { 2179 openfn |= (1<<4);2185 state->openfn |= (1<<4); 2180 2186 } 2181 2187 if (!(flags & O_EXCL)) { 2182 2188 if (flags & O_TRUNC) 2183 openfn |= (1<<1);2189 state->openfn |= (1<<1); 2184 2190 else 2185 openfn |= (1<<0);2186 } 2187 2188 accessmode= (share_mode<<4);2191 state->openfn |= (1<<0); 2192 } 2193 2194 state->dos_deny = (share_mode<<4); 2189 2195 2190 2196 if ((flags & O_ACCMODE) == O_RDWR) { 2191 accessmode|= 2;2197 state->dos_deny |= 2; 2192 2198 } else if ((flags & O_ACCMODE) == O_WRONLY) { 2193 accessmode|= 1;2199 state->dos_deny |= 1; 2194 2200 } 2195 2201 2196 2202 #if defined(O_SYNC) 2197 2203 if ((flags & O_SYNC) == O_SYNC) { 2198 accessmode|= (1<<14);2204 state->dos_deny |= (1<<14); 2199 2205 } 2200 2206 #endif /* O_SYNC */ 2201 2207 2202 2208 if (share_mode == DENY_FCB) { 2203 accessmode= 0xFF;2209 state->dos_deny = 0xFF; 2204 2210 } 2205 2211 … … 2208 2214 SSVAL(state->vwv + 1, 0, 0); 2209 2215 SSVAL(state->vwv + 2, 0, 0); /* no additional info */ 2210 SSVAL(state->vwv + 3, 0, accessmode);2216 SSVAL(state->vwv + 3, 0, state->dos_deny); 2211 2217 SSVAL(state->vwv + 4, 0, aSYSTEM | aHIDDEN); 2212 2218 SSVAL(state->vwv + 5, 0, 0); 2213 2219 SIVAL(state->vwv + 6, 0, 0); 2214 SSVAL(state->vwv + 8, 0, openfn);2220 SSVAL(state->vwv + 8, 0, state->openfn); 2215 2221 SIVAL(state->vwv + 9, 0, 0); 2216 2222 SIVAL(state->vwv + 11, 0, 0); 2217 2223 SIVAL(state->vwv + 13, 0, 0); 2218 2224 2219 additional_flags = 0;2220 2221 2225 if (cli->use_oplocks) { 2222 2226 /* if using oplocks then ask for a batch oplock via 2223 2227 core and extended methods */ 2224 additional_flags =2228 state->additional_flags = 2225 2229 FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK; 2226 2230 SSVAL(state->vwv+2, 0, SVAL(state->vwv+2, 0) | 6); … … 2238 2242 state->bytes.iov_len = talloc_get_size(bytes); 2239 2243 2240 subreq = cli_smb_req_create(state, ev, cli, SMBopenX, additional_flags, 2244 subreq = cli_smb_req_create(state, ev, cli, SMBopenX, 2245 state->additional_flags, 2241 2246 15, state->vwv, 1, &state->bytes); 2242 2247 if (subreq == NULL) { … … 2279 2284 uint16_t *vwv; 2280 2285 NTSTATUS status; 2286 uint32_t access_mask, share_mode, create_disposition, create_options; 2281 2287 2282 2288 status = cli_smb_recv(subreq, 3, &wct, &vwv, NULL, NULL); 2283 if (!NT_STATUS_IS_OK(status)) { 2284 TALLOC_FREE(subreq); 2289 TALLOC_FREE(subreq); 2290 2291 if (NT_STATUS_IS_OK(status)) { 2292 state->fnum = SVAL(vwv+2, 0); 2293 tevent_req_done(req); 2294 return; 2295 } 2296 2297 if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { 2285 2298 tevent_req_nterror(req, status); 2286 2299 return; 2287 2300 } 2288 state->fnum = SVAL(vwv+2, 0); 2301 2302 /* 2303 * For the new shiny OS/X Lion SMB server, try a ntcreate 2304 * fallback. 2305 */ 2306 2307 if (!map_open_params_to_ntcreate(state->fname, state->dos_deny, 2308 state->openfn, &access_mask, 2309 &share_mode, &create_disposition, 2310 &create_options)) { 2311 tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); 2312 return; 2313 } 2314 2315 subreq = cli_ntcreate_send(state, state->ev, state->cli, 2316 state->fname, 0, access_mask, 2317 0, share_mode, create_disposition, 2318 create_options, 0); 2319 if (tevent_req_nomem(subreq, req)) { 2320 return; 2321 } 2322 tevent_req_set_callback(subreq, cli_open_ntcreate_done, req); 2323 } 2324 2325 static void cli_open_ntcreate_done(struct tevent_req *subreq) 2326 { 2327 struct tevent_req *req = tevent_req_callback_data( 2328 subreq, struct tevent_req); 2329 struct cli_open_state *state = tevent_req_data( 2330 req, struct cli_open_state); 2331 NTSTATUS status; 2332 2333 status = cli_ntcreate_recv(subreq, &state->fnum); 2334 TALLOC_FREE(subreq); 2335 2336 if (!NT_STATUS_IS_OK(status)) { 2337 tevent_req_nterror(req, status); 2338 return; 2339 } 2289 2340 tevent_req_done(req); 2290 2341 }
Note:
See TracChangeset
for help on using the changeset viewer.