Deleted Added
full compact
smb_conn.c (78161) smb_conn.c (87192)
1/*
2 * Copyright (c) 2000-2001 Boris Popov
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 15 unchanged lines hidden (view full) ---

24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
1/*
2 * Copyright (c) 2000-2001 Boris Popov
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 15 unchanged lines hidden (view full) ---

24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $FreeBSD: head/sys/netsmb/smb_conn.c 78161 2001-06-13 10:58:39Z peter $
32 * $FreeBSD: head/sys/netsmb/smb_conn.c 87192 2001-12-02 08:47:29Z bp $
33 */
34
35/*
36 * Connection engine.
37 */
38
39#include <sys/param.h>
40#include <sys/systm.h>

--- 15 unchanged lines hidden (view full) ---

56static struct smb_connobj smb_vclist;
57static int smb_vcnext = 1; /* next unique id for VC */
58
59SYSCTL_NODE(_net, OID_AUTO, smb, CTLFLAG_RW, NULL, "SMB protocol");
60
61MALLOC_DEFINE(M_SMBCONN, "SMB conn", "SMB connection");
62
63static void smb_co_init(struct smb_connobj *cp, int level, char *objname,
33 */
34
35/*
36 * Connection engine.
37 */
38
39#include <sys/param.h>
40#include <sys/systm.h>

--- 15 unchanged lines hidden (view full) ---

56static struct smb_connobj smb_vclist;
57static int smb_vcnext = 1; /* next unique id for VC */
58
59SYSCTL_NODE(_net, OID_AUTO, smb, CTLFLAG_RW, NULL, "SMB protocol");
60
61MALLOC_DEFINE(M_SMBCONN, "SMB conn", "SMB connection");
62
63static void smb_co_init(struct smb_connobj *cp, int level, char *objname,
64 struct proc *p);
64 struct thread *td);
65static void smb_co_done(struct smb_connobj *cp);
65static void smb_co_done(struct smb_connobj *cp);
66static int smb_co_lockstatus(struct smb_connobj *cp, struct proc *p);
66static int smb_co_lockstatus(struct smb_connobj *cp, struct thread *td);
67
68static int smb_vc_disconnect(struct smb_vc *vcp);
69static void smb_vc_free(struct smb_connobj *cp);
70static void smb_vc_gone(struct smb_connobj *cp, struct smb_cred *scred);
71static smb_co_free_t smb_share_free;
72static smb_co_gone_t smb_share_gone;
73
74static int smb_sysctl_treedump(SYSCTL_HANDLER_ARGS);
75
76SYSCTL_PROC(_net_smb, OID_AUTO, treedump, CTLFLAG_RD | CTLTYPE_OPAQUE,
77 NULL, 0, smb_sysctl_treedump, "S,treedump", "Requester tree");
78
79int
80smb_sm_init(void)
81{
82
67
68static int smb_vc_disconnect(struct smb_vc *vcp);
69static void smb_vc_free(struct smb_connobj *cp);
70static void smb_vc_gone(struct smb_connobj *cp, struct smb_cred *scred);
71static smb_co_free_t smb_share_free;
72static smb_co_gone_t smb_share_gone;
73
74static int smb_sysctl_treedump(SYSCTL_HANDLER_ARGS);
75
76SYSCTL_PROC(_net_smb, OID_AUTO, treedump, CTLFLAG_RD | CTLTYPE_OPAQUE,
77 NULL, 0, smb_sysctl_treedump, "S,treedump", "Requester tree");
78
79int
80smb_sm_init(void)
81{
82
83 smb_co_init(&smb_vclist, SMBL_SM, "smbsm", curproc);
84 smb_co_unlock(&smb_vclist, 0, curproc);
83 smb_co_init(&smb_vclist, SMBL_SM, "smbsm", curthread);
84 smb_co_unlock(&smb_vclist, 0, curthread);
85 return 0;
86}
87
88int
89smb_sm_done(void)
90{
91
92 /* XXX: hold the mutex */
93 if (smb_vclist.co_usecount > 1) {
94 SMBERROR("%d connections still active\n", smb_vclist.co_usecount - 1);
95 return EBUSY;
96 }
97 smb_co_done(&smb_vclist);
98 return 0;
99}
100
101static int
85 return 0;
86}
87
88int
89smb_sm_done(void)
90{
91
92 /* XXX: hold the mutex */
93 if (smb_vclist.co_usecount > 1) {
94 SMBERROR("%d connections still active\n", smb_vclist.co_usecount - 1);
95 return EBUSY;
96 }
97 smb_co_done(&smb_vclist);
98 return 0;
99}
100
101static int
102smb_sm_lockvclist(int flags, struct proc *p)
102smb_sm_lockvclist(int flags, struct thread *td)
103{
104
103{
104
105 return smb_co_lock(&smb_vclist, flags | LK_CANRECURSE, p);
105 return smb_co_lock(&smb_vclist, flags | LK_CANRECURSE, td);
106}
107
108static void
106}
107
108static void
109smb_sm_unlockvclist(struct proc *p)
109smb_sm_unlockvclist(struct thread *td)
110{
111
110{
111
112 smb_co_unlock(&smb_vclist, LK_RELEASE, p);
112 smb_co_unlock(&smb_vclist, LK_RELEASE, td);
113}
114
115static int
116smb_sm_lookupint(struct smb_vcspec *vcspec, struct smb_sharespec *shspec,
117 struct smb_cred *scred, struct smb_vc **vcpp)
118{
113}
114
115static int
116smb_sm_lookupint(struct smb_vcspec *vcspec, struct smb_sharespec *shspec,
117 struct smb_cred *scred, struct smb_vc **vcpp)
118{
119 struct proc *p = scred->scr_p;
119 struct thread *td = scred->scr_td;
120 struct smb_vc *vcp;
121 int exact = 1;
122 int error;
123
124 vcspec->shspec = shspec;
125 error = ENOENT;
126 SMBCO_FOREACH((struct smb_connobj*)vcp, &smb_vclist) {
120 struct smb_vc *vcp;
121 int exact = 1;
122 int error;
123
124 vcspec->shspec = shspec;
125 error = ENOENT;
126 SMBCO_FOREACH((struct smb_connobj*)vcp, &smb_vclist) {
127 error = smb_vc_lock(vcp, LK_EXCLUSIVE, p);
127 error = smb_vc_lock(vcp, LK_EXCLUSIVE, td);
128 if (error)
129 continue;
130 itry {
131 if ((vcp->obj.co_flags & SMBV_PRIVATE) ||
132 !CONNADDREQ(vcp->vc_paddr, vcspec->sap) ||
133 strcmp(vcp->vc_username, vcspec->username) != 0)
134 ithrow(1);
135 if (vcspec->owner != SMBM_ANY_OWNER) {

--- 15 unchanged lines hidden (view full) ---

151 if (smb_vc_access(vcp, scred, vcspec->mode) != 0)
152 ithrow(1);
153 vcspec->ssp = NULL;
154 if (shspec)
155 ithrow(smb_vc_lookupshare(vcp, shspec, scred, &vcspec->ssp));
156 error = 0;
157 break;
158 } icatch(error) {
128 if (error)
129 continue;
130 itry {
131 if ((vcp->obj.co_flags & SMBV_PRIVATE) ||
132 !CONNADDREQ(vcp->vc_paddr, vcspec->sap) ||
133 strcmp(vcp->vc_username, vcspec->username) != 0)
134 ithrow(1);
135 if (vcspec->owner != SMBM_ANY_OWNER) {

--- 15 unchanged lines hidden (view full) ---

151 if (smb_vc_access(vcp, scred, vcspec->mode) != 0)
152 ithrow(1);
153 vcspec->ssp = NULL;
154 if (shspec)
155 ithrow(smb_vc_lookupshare(vcp, shspec, scred, &vcspec->ssp));
156 error = 0;
157 break;
158 } icatch(error) {
159 smb_vc_unlock(vcp, 0, p);
159 smb_vc_unlock(vcp, 0, td);
160 } ifinally {
161 } iendtry;
162 if (error == 0)
163 break;
164 }
165 if (vcp) {
160 } ifinally {
161 } iendtry;
162 if (error == 0)
163 break;
164 }
165 if (vcp) {
166 smb_vc_ref(vcp, p);
166 smb_vc_ref(vcp);
167 *vcpp = vcp;
168 }
169 return error;
170}
171
172int
173smb_sm_lookup(struct smb_vcspec *vcspec, struct smb_sharespec *shspec,
174 struct smb_cred *scred, struct smb_vc **vcpp)
175{
167 *vcpp = vcp;
168 }
169 return error;
170}
171
172int
173smb_sm_lookup(struct smb_vcspec *vcspec, struct smb_sharespec *shspec,
174 struct smb_cred *scred, struct smb_vc **vcpp)
175{
176 struct proc *p = scred->scr_p;
176 struct thread *td = scred->scr_td;
177 struct smb_vc *vcp;
178 struct smb_share *ssp = NULL;
179 int error;
180
181 *vcpp = vcp = NULL;
182
177 struct smb_vc *vcp;
178 struct smb_share *ssp = NULL;
179 int error;
180
181 *vcpp = vcp = NULL;
182
183 error = smb_sm_lockvclist(LK_EXCLUSIVE, p);
183 error = smb_sm_lockvclist(LK_EXCLUSIVE, td);
184 if (error)
185 return error;
186 error = smb_sm_lookupint(vcspec, shspec, scred, vcpp);
187 if (error == 0 || (vcspec->flags & SMBV_CREATE) == 0) {
184 if (error)
185 return error;
186 error = smb_sm_lookupint(vcspec, shspec, scred, vcpp);
187 if (error == 0 || (vcspec->flags & SMBV_CREATE) == 0) {
188 smb_sm_unlockvclist(p);
188 smb_sm_unlockvclist(td);
189 return error;
190 }
191 error = smb_sm_lookupint(vcspec, NULL, scred, &vcp);
192 if (error) {
193 error = smb_vc_create(vcspec, scred, &vcp);
194 if (error)
195 goto out;
196 error = smb_vc_connect(vcp, scred);

--- 6 unchanged lines hidden (view full) ---

203 if (error)
204 goto out;
205 error = smb_smb_treeconnect(ssp, scred);
206 if (error == 0)
207 vcspec->ssp = ssp;
208 else
209 smb_share_put(ssp, scred);
210out:
189 return error;
190 }
191 error = smb_sm_lookupint(vcspec, NULL, scred, &vcp);
192 if (error) {
193 error = smb_vc_create(vcspec, scred, &vcp);
194 if (error)
195 goto out;
196 error = smb_vc_connect(vcp, scred);

--- 6 unchanged lines hidden (view full) ---

203 if (error)
204 goto out;
205 error = smb_smb_treeconnect(ssp, scred);
206 if (error == 0)
207 vcspec->ssp = ssp;
208 else
209 smb_share_put(ssp, scred);
210out:
211 smb_sm_unlockvclist(p);
211 smb_sm_unlockvclist(td);
212 if (error == 0)
213 *vcpp = vcp;
214 else if (vcp)
215 smb_vc_put(vcp, scred);
216 return error;
217}
218
219/*
220 * Common code for connection object
221 */
222static void
212 if (error == 0)
213 *vcpp = vcp;
214 else if (vcp)
215 smb_vc_put(vcp, scred);
216 return error;
217}
218
219/*
220 * Common code for connection object
221 */
222static void
223smb_co_init(struct smb_connobj *cp, int level, char *objname, struct proc *p)
223smb_co_init(struct smb_connobj *cp, int level, char *objname, struct thread *td)
224{
225 SLIST_INIT(&cp->co_children);
226 smb_sl_init(&cp->co_interlock, objname);
227 lockinit(&cp->co_lock, PZERO, objname, 0, 0);
228 cp->co_level = level;
229 cp->co_usecount = 1;
224{
225 SLIST_INIT(&cp->co_children);
226 smb_sl_init(&cp->co_interlock, objname);
227 lockinit(&cp->co_lock, PZERO, objname, 0, 0);
228 cp->co_level = level;
229 cp->co_usecount = 1;
230 KASSERT(smb_co_lock(cp, LK_EXCLUSIVE, p) == 0, ("smb_co_init: lock failed"));
230 KASSERT(smb_co_lock(cp, LK_EXCLUSIVE, td) == 0, ("smb_co_init: lock failed"));
231}
232
233static void
234smb_co_done(struct smb_connobj *cp)
235{
236 smb_sl_destroy(&cp->co_interlock);
237 lockdestroy(&cp->co_lock);
238}
239
240static void
241smb_co_gone(struct smb_connobj *cp, struct smb_cred *scred)
242{
243 struct smb_connobj *parent;
244
245 if (cp->co_gone)
246 cp->co_gone(cp, scred);
247 parent = cp->co_parent;
248 if (parent) {
231}
232
233static void
234smb_co_done(struct smb_connobj *cp)
235{
236 smb_sl_destroy(&cp->co_interlock);
237 lockdestroy(&cp->co_lock);
238}
239
240static void
241smb_co_gone(struct smb_connobj *cp, struct smb_cred *scred)
242{
243 struct smb_connobj *parent;
244
245 if (cp->co_gone)
246 cp->co_gone(cp, scred);
247 parent = cp->co_parent;
248 if (parent) {
249 smb_co_lock(parent, LK_EXCLUSIVE, scred->scr_p);
249 smb_co_lock(parent, LK_EXCLUSIVE, scred->scr_td);
250 SLIST_REMOVE(&parent->co_children, cp, smb_connobj, co_next);
251 smb_co_put(parent, scred);
252 }
253 if (cp->co_free)
254 cp->co_free(cp);
255}
256
257void
250 SLIST_REMOVE(&parent->co_children, cp, smb_connobj, co_next);
251 smb_co_put(parent, scred);
252 }
253 if (cp->co_free)
254 cp->co_free(cp);
255}
256
257void
258smb_co_ref(struct smb_connobj *cp, struct proc *p)
258smb_co_ref(struct smb_connobj *cp)
259{
260
261 SMB_CO_LOCK(cp);
262 cp->co_usecount++;
263 SMB_CO_UNLOCK(cp);
264}
265
266void
267smb_co_rele(struct smb_connobj *cp, struct smb_cred *scred)
268{
259{
260
261 SMB_CO_LOCK(cp);
262 cp->co_usecount++;
263 SMB_CO_UNLOCK(cp);
264}
265
266void
267smb_co_rele(struct smb_connobj *cp, struct smb_cred *scred)
268{
269 struct proc *p = scred->scr_p;
269 struct thread *td = scred->scr_td;
270
271 SMB_CO_LOCK(cp);
272 if (cp->co_usecount > 1) {
273 cp->co_usecount--;
274 SMB_CO_UNLOCK(cp);
275 return;
276 }
277 if (cp->co_usecount == 0) {
278 SMBERROR("negative use_count for object %d", cp->co_level);
279 SMB_CO_UNLOCK(cp);
280 return;
281 }
282 cp->co_usecount--;
283 cp->co_flags |= SMBO_GONE;
284
270
271 SMB_CO_LOCK(cp);
272 if (cp->co_usecount > 1) {
273 cp->co_usecount--;
274 SMB_CO_UNLOCK(cp);
275 return;
276 }
277 if (cp->co_usecount == 0) {
278 SMBERROR("negative use_count for object %d", cp->co_level);
279 SMB_CO_UNLOCK(cp);
280 return;
281 }
282 cp->co_usecount--;
283 cp->co_flags |= SMBO_GONE;
284
285 lockmgr(&cp->co_lock, LK_DRAIN | LK_INTERLOCK, &cp->co_interlock, p);
285 lockmgr(&cp->co_lock, LK_DRAIN | LK_INTERLOCK, &cp->co_interlock, td);
286 smb_co_gone(cp, scred);
287}
288
289int
290smb_co_get(struct smb_connobj *cp, int flags, struct smb_cred *scred)
291{
292 int error;
293
294 if ((flags & LK_INTERLOCK) == 0)
295 SMB_CO_LOCK(cp);
296 cp->co_usecount++;
286 smb_co_gone(cp, scred);
287}
288
289int
290smb_co_get(struct smb_connobj *cp, int flags, struct smb_cred *scred)
291{
292 int error;
293
294 if ((flags & LK_INTERLOCK) == 0)
295 SMB_CO_LOCK(cp);
296 cp->co_usecount++;
297 error = smb_co_lock(cp, flags | LK_INTERLOCK, scred->scr_p);
297 error = smb_co_lock(cp, flags | LK_INTERLOCK, scred->scr_td);
298 if (error) {
299 SMB_CO_LOCK(cp);
300 cp->co_usecount--;
301 SMB_CO_UNLOCK(cp);
302 return error;
303 }
304 return 0;
305}
306
307void
308smb_co_put(struct smb_connobj *cp, struct smb_cred *scred)
309{
298 if (error) {
299 SMB_CO_LOCK(cp);
300 cp->co_usecount--;
301 SMB_CO_UNLOCK(cp);
302 return error;
303 }
304 return 0;
305}
306
307void
308smb_co_put(struct smb_connobj *cp, struct smb_cred *scred)
309{
310 struct proc *p = scred->scr_p;
310 struct thread *td = scred->scr_td;
311 int flags;
312
313 flags = LK_RELEASE;
314 SMB_CO_LOCK(cp);
315 if (cp->co_usecount > 1) {
316 cp->co_usecount--;
317 } else if (cp->co_usecount == 1) {
318 cp->co_usecount--;
319 cp->co_flags |= SMBO_GONE;
320 flags = LK_DRAIN;
321 } else {
322 SMBERROR("negative usecount");
323 }
311 int flags;
312
313 flags = LK_RELEASE;
314 SMB_CO_LOCK(cp);
315 if (cp->co_usecount > 1) {
316 cp->co_usecount--;
317 } else if (cp->co_usecount == 1) {
318 cp->co_usecount--;
319 cp->co_flags |= SMBO_GONE;
320 flags = LK_DRAIN;
321 } else {
322 SMBERROR("negative usecount");
323 }
324 lockmgr(&cp->co_lock, LK_RELEASE | LK_INTERLOCK, &cp->co_interlock, p);
324 lockmgr(&cp->co_lock, LK_RELEASE | LK_INTERLOCK, &cp->co_interlock, td);
325 if ((cp->co_flags & SMBO_GONE) == 0)
326 return;
325 if ((cp->co_flags & SMBO_GONE) == 0)
326 return;
327 lockmgr(&cp->co_lock, LK_DRAIN, NULL, p);
327 lockmgr(&cp->co_lock, LK_DRAIN, NULL, td);
328 smb_co_gone(cp, scred);
329}
330
331int
328 smb_co_gone(cp, scred);
329}
330
331int
332smb_co_lockstatus(struct smb_connobj *cp, struct proc *p)
332smb_co_lockstatus(struct smb_connobj *cp, struct thread *td)
333{
333{
334 return lockstatus(&cp->co_lock, p);
334 return lockstatus(&cp->co_lock, td);
335}
336
337int
335}
336
337int
338smb_co_lock(struct smb_connobj *cp, int flags, struct proc *p)
338smb_co_lock(struct smb_connobj *cp, int flags, struct thread *td)
339{
340
341 if (cp->co_flags & SMBO_GONE)
342 return EINVAL;
343 if ((flags & LK_TYPE_MASK) == 0)
344 flags |= LK_EXCLUSIVE;
339{
340
341 if (cp->co_flags & SMBO_GONE)
342 return EINVAL;
343 if ((flags & LK_TYPE_MASK) == 0)
344 flags |= LK_EXCLUSIVE;
345 if (smb_co_lockstatus(cp, p) == LK_EXCLUSIVE &&
345 if (smb_co_lockstatus(cp, td) == LK_EXCLUSIVE &&
346 (flags & LK_CANRECURSE) == 0) {
347 SMBERROR("recursive lock for object %d\n", cp->co_level);
348 return 0;
349 }
346 (flags & LK_CANRECURSE) == 0) {
347 SMBERROR("recursive lock for object %d\n", cp->co_level);
348 return 0;
349 }
350 return lockmgr(&cp->co_lock, flags, &cp->co_interlock, p);
350 return lockmgr(&cp->co_lock, flags, &cp->co_interlock, td);
351}
352
353void
351}
352
353void
354smb_co_unlock(struct smb_connobj *cp, int flags, struct proc *p)
354smb_co_unlock(struct smb_connobj *cp, int flags, struct thread *td)
355{
355{
356 (void)lockmgr(&cp->co_lock, flags | LK_RELEASE, &cp->co_interlock, p);
356 (void)lockmgr(&cp->co_lock, flags | LK_RELEASE, &cp->co_interlock, td);
357}
358
359static void
360smb_co_addchild(struct smb_connobj *parent, struct smb_connobj *child)
361{
357}
358
359static void
360smb_co_addchild(struct smb_connobj *parent, struct smb_connobj *child)
361{
362 KASSERT(smb_co_lockstatus(parent, curproc) == LK_EXCLUSIVE, ("smb_co_addchild: parent not locked"));
363 KASSERT(smb_co_lockstatus(child, curproc) == LK_EXCLUSIVE, ("smb_co_addchild: child not locked"));
362 KASSERT(smb_co_lockstatus(parent, curthread) == LK_EXCLUSIVE, ("smb_co_addchild: parent not locked"));
363 KASSERT(smb_co_lockstatus(child, curthread) == LK_EXCLUSIVE, ("smb_co_addchild: child not locked"));
364
364
365 smb_co_ref(parent, curproc);
365 smb_co_ref(parent);
366 SLIST_INSERT_HEAD(&parent->co_children, child, co_next);
367 child->co_parent = parent;
368}
369
370/*
371 * Session implementation
372 */
373
374int
375smb_vc_create(struct smb_vcspec *vcspec,
376 struct smb_cred *scred, struct smb_vc **vcpp)
377{
378 struct smb_vc *vcp;
366 SLIST_INSERT_HEAD(&parent->co_children, child, co_next);
367 child->co_parent = parent;
368}
369
370/*
371 * Session implementation
372 */
373
374int
375smb_vc_create(struct smb_vcspec *vcspec,
376 struct smb_cred *scred, struct smb_vc **vcpp)
377{
378 struct smb_vc *vcp;
379 struct proc *p = scred->scr_p;
379 struct thread *td = scred->scr_td;
380 struct ucred *cred = scred->scr_cred;
381 uid_t uid = vcspec->owner;
382 gid_t gid = vcspec->group;
383 uid_t realuid = cred->cr_uid;
384 char *domain = vcspec->domain;
385 int error, isroot;
386
387 isroot = smb_suser(cred) == 0;
388 /*
389 * Only superuser can create VCs with different uid and gid
390 */
391 if (uid != SMBM_ANY_OWNER && uid != realuid && !isroot)
392 return EPERM;
393 if (gid != SMBM_ANY_GROUP && !groupmember(gid, cred) && !isroot)
394 return EPERM;
395
396 vcp = smb_zmalloc(sizeof(*vcp), M_SMBCONN, M_WAITOK);
380 struct ucred *cred = scred->scr_cred;
381 uid_t uid = vcspec->owner;
382 gid_t gid = vcspec->group;
383 uid_t realuid = cred->cr_uid;
384 char *domain = vcspec->domain;
385 int error, isroot;
386
387 isroot = smb_suser(cred) == 0;
388 /*
389 * Only superuser can create VCs with different uid and gid
390 */
391 if (uid != SMBM_ANY_OWNER && uid != realuid && !isroot)
392 return EPERM;
393 if (gid != SMBM_ANY_GROUP && !groupmember(gid, cred) && !isroot)
394 return EPERM;
395
396 vcp = smb_zmalloc(sizeof(*vcp), M_SMBCONN, M_WAITOK);
397 smb_co_init(VCTOCP(vcp), SMBL_VC, "smb_vc", p);
397 smb_co_init(VCTOCP(vcp), SMBL_VC, "smb_vc", td);
398 vcp->obj.co_free = smb_vc_free;
399 vcp->obj.co_gone = smb_vc_gone;
400 vcp->vc_number = smb_vcnext++;
401 vcp->vc_timo = SMB_DEFRQTIMO;
402 vcp->vc_smbuid = SMB_UID_UNKNOWN;
403 vcp->vc_mode = vcspec->rights & SMBM_MASK;
404 vcp->obj.co_flags = vcspec->flags & (SMBV_PRIVATE | SMBV_SINGLESHARE);
405 vcp->vc_tdesc = &smb_tran_nbtcp_desc;

--- 77 unchanged lines hidden (view full) ---

483smb_vc_gone(struct smb_connobj *cp, struct smb_cred *scred)
484{
485 struct smb_vc *vcp = CPTOVC(cp);
486
487 smb_vc_disconnect(vcp);
488}
489
490void
398 vcp->obj.co_free = smb_vc_free;
399 vcp->obj.co_gone = smb_vc_gone;
400 vcp->vc_number = smb_vcnext++;
401 vcp->vc_timo = SMB_DEFRQTIMO;
402 vcp->vc_smbuid = SMB_UID_UNKNOWN;
403 vcp->vc_mode = vcspec->rights & SMBM_MASK;
404 vcp->obj.co_flags = vcspec->flags & (SMBV_PRIVATE | SMBV_SINGLESHARE);
405 vcp->vc_tdesc = &smb_tran_nbtcp_desc;

--- 77 unchanged lines hidden (view full) ---

483smb_vc_gone(struct smb_connobj *cp, struct smb_cred *scred)
484{
485 struct smb_vc *vcp = CPTOVC(cp);
486
487 smb_vc_disconnect(vcp);
488}
489
490void
491smb_vc_ref(struct smb_vc *vcp, struct proc *p)
491smb_vc_ref(struct smb_vc *vcp)
492{
492{
493 smb_co_ref(VCTOCP(vcp), p);
493 smb_co_ref(VCTOCP(vcp));
494}
495
496void
497smb_vc_rele(struct smb_vc *vcp, struct smb_cred *scred)
498{
499 smb_co_rele(VCTOCP(vcp), scred);
500}
501

--- 5 unchanged lines hidden (view full) ---

507
508void
509smb_vc_put(struct smb_vc *vcp, struct smb_cred *scred)
510{
511 smb_co_put(VCTOCP(vcp), scred);
512}
513
514int
494}
495
496void
497smb_vc_rele(struct smb_vc *vcp, struct smb_cred *scred)
498{
499 smb_co_rele(VCTOCP(vcp), scred);
500}
501

--- 5 unchanged lines hidden (view full) ---

507
508void
509smb_vc_put(struct smb_vc *vcp, struct smb_cred *scred)
510{
511 smb_co_put(VCTOCP(vcp), scred);
512}
513
514int
515smb_vc_lock(struct smb_vc *vcp, int flags, struct proc *p)
515smb_vc_lock(struct smb_vc *vcp, int flags, struct thread *td)
516{
516{
517 return smb_co_lock(VCTOCP(vcp), flags, p);
517 return smb_co_lock(VCTOCP(vcp), flags, td);
518}
519
520void
518}
519
520void
521smb_vc_unlock(struct smb_vc *vcp, int flags, struct proc *p)
521smb_vc_unlock(struct smb_vc *vcp, int flags, struct thread *td)
522{
522{
523 smb_co_unlock(VCTOCP(vcp), flags, p);
523 smb_co_unlock(VCTOCP(vcp), flags, td);
524}
525
526int
527smb_vc_access(struct smb_vc *vcp, struct smb_cred *scred, mode_t mode)
528{
529 struct ucred *cred = scred->scr_cred;
530
531 if (smb_suser(cred) == 0 || cred->cr_uid == vcp->vc_uid)

--- 35 unchanged lines hidden (view full) ---

567/*
568 * Lookup share in the given VC. Share referenced and locked on return.
569 * VC expected to be locked on entry and will be left locked on exit.
570 */
571int
572smb_vc_lookupshare(struct smb_vc *vcp, struct smb_sharespec *dp,
573 struct smb_cred *scred, struct smb_share **sspp)
574{
524}
525
526int
527smb_vc_access(struct smb_vc *vcp, struct smb_cred *scred, mode_t mode)
528{
529 struct ucred *cred = scred->scr_cred;
530
531 if (smb_suser(cred) == 0 || cred->cr_uid == vcp->vc_uid)

--- 35 unchanged lines hidden (view full) ---

567/*
568 * Lookup share in the given VC. Share referenced and locked on return.
569 * VC expected to be locked on entry and will be left locked on exit.
570 */
571int
572smb_vc_lookupshare(struct smb_vc *vcp, struct smb_sharespec *dp,
573 struct smb_cred *scred, struct smb_share **sspp)
574{
575 struct proc *p = scred->scr_p;
575 struct thread *td = scred->scr_td;
576 struct smb_share *ssp = NULL;
577 int error;
578
579 *sspp = NULL;
580 dp->scred = scred;
581 SMBCO_FOREACH((struct smb_connobj*)ssp, VCTOCP(vcp)) {
576 struct smb_share *ssp = NULL;
577 int error;
578
579 *sspp = NULL;
580 dp->scred = scred;
581 SMBCO_FOREACH((struct smb_connobj*)ssp, VCTOCP(vcp)) {
582 error = smb_share_lock(ssp, LK_EXCLUSIVE, p);
582 error = smb_share_lock(ssp, LK_EXCLUSIVE, td);
583 if (error)
584 continue;
585 if (smb_vc_cmpshare(ssp, dp) == 0)
586 break;
583 if (error)
584 continue;
585 if (smb_vc_cmpshare(ssp, dp) == 0)
586 break;
587 smb_share_unlock(ssp, 0, p);
587 smb_share_unlock(ssp, 0, td);
588 }
589 if (ssp) {
588 }
589 if (ssp) {
590 smb_share_ref(ssp, p);
590 smb_share_ref(ssp);
591 *sspp = ssp;
592 error = 0;
593 } else
594 error = ENOENT;
595 return error;
596}
597
598int

--- 62 unchanged lines hidden (view full) ---

661 * Connection expected to be locked on entry. Share will be returned
662 * in locked state.
663 */
664int
665smb_share_create(struct smb_vc *vcp, struct smb_sharespec *shspec,
666 struct smb_cred *scred, struct smb_share **sspp)
667{
668 struct smb_share *ssp;
591 *sspp = ssp;
592 error = 0;
593 } else
594 error = ENOENT;
595 return error;
596}
597
598int

--- 62 unchanged lines hidden (view full) ---

661 * Connection expected to be locked on entry. Share will be returned
662 * in locked state.
663 */
664int
665smb_share_create(struct smb_vc *vcp, struct smb_sharespec *shspec,
666 struct smb_cred *scred, struct smb_share **sspp)
667{
668 struct smb_share *ssp;
669 struct proc *p = scred->scr_p;
669 struct thread *td = scred->scr_td;
670 struct ucred *cred = scred->scr_cred;
671 uid_t realuid = cred->cr_uid;
672 uid_t uid = shspec->owner;
673 gid_t gid = shspec->group;
674 int error, isroot;
675
676 isroot = smb_suser(cred) == 0;
677 /*

--- 8 unchanged lines hidden (view full) ---

686 smb_share_put(ssp, scred);
687 return EEXIST;
688 }
689 if (uid == SMBM_ANY_OWNER)
690 uid = realuid;
691 if (gid == SMBM_ANY_GROUP)
692 gid = cred->cr_groups[0];
693 ssp = smb_zmalloc(sizeof(*ssp), M_SMBCONN, M_WAITOK);
670 struct ucred *cred = scred->scr_cred;
671 uid_t realuid = cred->cr_uid;
672 uid_t uid = shspec->owner;
673 gid_t gid = shspec->group;
674 int error, isroot;
675
676 isroot = smb_suser(cred) == 0;
677 /*

--- 8 unchanged lines hidden (view full) ---

686 smb_share_put(ssp, scred);
687 return EEXIST;
688 }
689 if (uid == SMBM_ANY_OWNER)
690 uid = realuid;
691 if (gid == SMBM_ANY_GROUP)
692 gid = cred->cr_groups[0];
693 ssp = smb_zmalloc(sizeof(*ssp), M_SMBCONN, M_WAITOK);
694 smb_co_init(SSTOCP(ssp), SMBL_SHARE, "smbss", p);
694 smb_co_init(SSTOCP(ssp), SMBL_SHARE, "smbss", td);
695 ssp->obj.co_free = smb_share_free;
696 ssp->obj.co_gone = smb_share_gone;
697 smb_sl_init(&ssp->ss_stlock, "ssstlock");
698 ssp->ss_name = smb_strdup(shspec->name);
699 if (shspec->pass && shspec->pass[0])
700 ssp->ss_pass = smb_strdup(shspec->pass);
701 ssp->ss_type = shspec->stype;
702 ssp->ss_tid = SMB_TID_UNKNOWN;

--- 21 unchanged lines hidden (view full) ---

724smb_share_gone(struct smb_connobj *cp, struct smb_cred *scred)
725{
726 struct smb_share *ssp = CPTOSS(cp);
727
728 smb_smb_treedisconnect(ssp, scred);
729}
730
731void
695 ssp->obj.co_free = smb_share_free;
696 ssp->obj.co_gone = smb_share_gone;
697 smb_sl_init(&ssp->ss_stlock, "ssstlock");
698 ssp->ss_name = smb_strdup(shspec->name);
699 if (shspec->pass && shspec->pass[0])
700 ssp->ss_pass = smb_strdup(shspec->pass);
701 ssp->ss_type = shspec->stype;
702 ssp->ss_tid = SMB_TID_UNKNOWN;

--- 21 unchanged lines hidden (view full) ---

724smb_share_gone(struct smb_connobj *cp, struct smb_cred *scred)
725{
726 struct smb_share *ssp = CPTOSS(cp);
727
728 smb_smb_treedisconnect(ssp, scred);
729}
730
731void
732smb_share_ref(struct smb_share *ssp, struct proc *p)
732smb_share_ref(struct smb_share *ssp)
733{
733{
734 smb_co_ref(SSTOCP(ssp), p);
734 smb_co_ref(SSTOCP(ssp));
735}
736
737void
738smb_share_rele(struct smb_share *ssp, struct smb_cred *scred)
739{
740 smb_co_rele(SSTOCP(ssp), scred);
741}
742

--- 5 unchanged lines hidden (view full) ---

748
749void
750smb_share_put(struct smb_share *ssp, struct smb_cred *scred)
751{
752 smb_co_put(SSTOCP(ssp), scred);
753}
754
755int
735}
736
737void
738smb_share_rele(struct smb_share *ssp, struct smb_cred *scred)
739{
740 smb_co_rele(SSTOCP(ssp), scred);
741}
742

--- 5 unchanged lines hidden (view full) ---

748
749void
750smb_share_put(struct smb_share *ssp, struct smb_cred *scred)
751{
752 smb_co_put(SSTOCP(ssp), scred);
753}
754
755int
756smb_share_lock(struct smb_share *ssp, int flags, struct proc *p)
756smb_share_lock(struct smb_share *ssp, int flags, struct thread *td)
757{
757{
758 return smb_co_lock(SSTOCP(ssp), flags, p);
758 return smb_co_lock(SSTOCP(ssp), flags, td);
759}
760
761void
759}
760
761void
762smb_share_unlock(struct smb_share *ssp, int flags, struct proc *p)
762smb_share_unlock(struct smb_share *ssp, int flags, struct thread *td)
763{
763{
764 smb_co_unlock(SSTOCP(ssp), flags, p);
764 smb_co_unlock(SSTOCP(ssp), flags, td);
765}
766
767int
768smb_share_access(struct smb_share *ssp, struct smb_cred *scred, mode_t mode)
769{
770 struct ucred *cred = scred->scr_cred;
771
772 if (smb_suser(cred) == 0 || cred->cr_uid == ssp->ss_uid)

--- 47 unchanged lines hidden (view full) ---

820}
821
822/*
823 * Dump an entire tree into sysctl call
824 */
825static int
826smb_sysctl_treedump(SYSCTL_HANDLER_ARGS)
827{
765}
766
767int
768smb_share_access(struct smb_share *ssp, struct smb_cred *scred, mode_t mode)
769{
770 struct ucred *cred = scred->scr_cred;
771
772 if (smb_suser(cred) == 0 || cred->cr_uid == ssp->ss_uid)

--- 47 unchanged lines hidden (view full) ---

820}
821
822/*
823 * Dump an entire tree into sysctl call
824 */
825static int
826smb_sysctl_treedump(SYSCTL_HANDLER_ARGS)
827{
828 struct proc *p = req->p;
828 struct thread *td = req->td;
829 struct smb_cred scred;
830 struct smb_vc *vcp;
831 struct smb_share *ssp;
832 struct smb_vc_info vci;
833 struct smb_share_info ssi;
834 int error, itype;
835
829 struct smb_cred scred;
830 struct smb_vc *vcp;
831 struct smb_share *ssp;
832 struct smb_vc_info vci;
833 struct smb_share_info ssi;
834 int error, itype;
835
836 smb_makescred(&scred, p, p->p_ucred);
837 error = smb_sm_lockvclist(LK_SHARED, p);
836 smb_makescred(&scred, td, td->td_proc->p_ucred);
837 error = smb_sm_lockvclist(LK_SHARED, td);
838 if (error)
839 return error;
840 SMBCO_FOREACH((struct smb_connobj*)vcp, &smb_vclist) {
838 if (error)
839 return error;
840 SMBCO_FOREACH((struct smb_connobj*)vcp, &smb_vclist) {
841 error = smb_vc_lock(vcp, LK_SHARED, p);
841 error = smb_vc_lock(vcp, LK_SHARED, td);
842 if (error)
843 continue;
844 smb_vc_getinfo(vcp, &vci);
845 error = SYSCTL_OUT(req, &vci, sizeof(struct smb_vc_info));
846 if (error) {
842 if (error)
843 continue;
844 smb_vc_getinfo(vcp, &vci);
845 error = SYSCTL_OUT(req, &vci, sizeof(struct smb_vc_info));
846 if (error) {
847 smb_vc_unlock(vcp, 0, p);
847 smb_vc_unlock(vcp, 0, td);
848 break;
849 }
850 SMBCO_FOREACH((struct smb_connobj*)ssp, VCTOCP(vcp)) {
848 break;
849 }
850 SMBCO_FOREACH((struct smb_connobj*)ssp, VCTOCP(vcp)) {
851 error = smb_share_lock(ssp, LK_SHARED, p);
851 error = smb_share_lock(ssp, LK_SHARED, td);
852 if (error) {
853 error = 0;
854 continue;
855 }
856 smb_share_getinfo(ssp, &ssi);
852 if (error) {
853 error = 0;
854 continue;
855 }
856 smb_share_getinfo(ssp, &ssi);
857 smb_share_unlock(ssp, 0, p);
857 smb_share_unlock(ssp, 0, td);
858 error = SYSCTL_OUT(req, &ssi, sizeof(struct smb_share_info));
859 if (error)
860 break;
861 }
858 error = SYSCTL_OUT(req, &ssi, sizeof(struct smb_share_info));
859 if (error)
860 break;
861 }
862 smb_vc_unlock(vcp, 0, p);
862 smb_vc_unlock(vcp, 0, td);
863 if (error)
864 break;
865 }
866 if (!error) {
867 itype = SMB_INFO_NONE;
868 error = SYSCTL_OUT(req, &itype, sizeof(itype));
869 }
863 if (error)
864 break;
865 }
866 if (!error) {
867 itype = SMB_INFO_NONE;
868 error = SYSCTL_OUT(req, &itype, sizeof(itype));
869 }
870 smb_sm_unlockvclist(p);
870 smb_sm_unlockvclist(td);
871 return error;
872}
871 return error;
872}