diff options
Diffstat (limited to 'usr/src/lib/libsmbfs/smb/connect.c')
-rw-r--r-- | usr/src/lib/libsmbfs/smb/connect.c | 75 |
1 files changed, 62 insertions, 13 deletions
diff --git a/usr/src/lib/libsmbfs/smb/connect.c b/usr/src/lib/libsmbfs/smb/connect.c index a45fa90958..c231fe0e8a 100644 --- a/usr/src/lib/libsmbfs/smb/connect.c +++ b/usr/src/lib/libsmbfs/smb/connect.c @@ -51,6 +51,7 @@ #include <netinet/in.h> #include <netinet/tcp.h> #include <arpa/inet.h> +#include <uuid/uuid.h> #include <netsmb/smb.h> #include <netsmb/smb_lib.h> @@ -59,6 +60,8 @@ #include <netsmb/nb_lib.h> #include <netsmb/smb_dev.h> +#include <cflib.h> + #include "charsets.h" #include "private.h" #include "smb_crypt.h" @@ -115,12 +118,18 @@ smb_iod_state_name(enum smbiod_state st) /* * Make a new connection, or reconnect. + * + * This is called first from the door service thread in smbiod + * (so that can report success or failure to the door client) + * and thereafter it's called when we need to reconnect after a + * network outage (or whatever might cause connection loss). */ int smb_iod_connect(smb_ctx_t *ctx) { smbioc_ossn_t *ossn = &ctx->ct_ssn; smbioc_ssn_work_t *work = &ctx->ct_work; + char *uuid_str; int err; struct mbdata blob; char *nego_buf = NULL; @@ -151,6 +160,20 @@ smb_iod_connect(smb_ctx_t *ctx) } /* + * Get local machine uuid. + */ + uuid_str = cf_get_client_uuid(); + if (uuid_str == NULL) { + err = EINVAL; + smb_error(dgettext(TEXT_DOMAIN, + "can't get local UUID"), err); + return (err); + } + (void) uuid_parse(uuid_str, ctx->ct_work.wk_cl_guid); + free(uuid_str); + uuid_str = NULL; + + /* * We're called with each IP address * already copied into ct_srvaddr. */ @@ -227,6 +250,13 @@ out: return (err); } +/* + * smb_ssnsetup_spnego + * + * This does an SMB session setup sequence using SPNEGO. + * The state changes seen during this sequence are there + * just to help track what's going on. + */ int smb_ssnsetup_spnego(struct smb_ctx *ctx, struct mbdata *hint_mb) { @@ -249,25 +279,39 @@ smb_ssnsetup_spnego(struct smb_ctx *ctx, struct mbdata *hint_mb) } for (;;) { err = smb__ssnsetup(ctx, &send_mb, &recv_mb); - if (err != 0 && err != EINPROGRESS) { - DPRINT("smb__ssnsetup, err=%d", err); - goto out; - } - DPRINT("smb__ssnsetup, new state=%s", + DPRINT("smb__ssnsetup rc=%d, new state=%s", err, smb_iod_state_name(work->wk_out_state)); - if (work->wk_out_state == SMBIOD_ST_AUTHOK) { - err = 0; + + if (err == 0) { + /* + * Session setup complete w/ success. + * Should have state AUTHOK + */ + if (work->wk_out_state != SMBIOD_ST_AUTHOK) { + DPRINT("Wrong state (expected AUTHOK)"); + } break; } - if (work->wk_out_state == SMBIOD_ST_AUTHFAIL) { - err = EAUTH; + + if (err != EINPROGRESS) { + /* + * Session setup complete w/ failure. + * Should have state AUTHFAIL + */ + if (work->wk_out_state != SMBIOD_ST_AUTHFAIL) { + DPRINT("Wrong state (expected AUTHFAIL)"); + } goto out; } + + /* + * err == EINPROGRESS + * Session setup continuing. + * Should have state AUTHCONT + */ if (work->wk_out_state != SMBIOD_ST_AUTHCONT) { - err = EPROTO; - goto out; + DPRINT("Wrong state (expected AUTHCONT)"); } - /* state == SMBIOD_ST_AUTHCONT */ /* middle calls get both in, out */ err = ssp_ctx_next_token(ctx, &recv_mb, &send_mb); @@ -277,7 +321,12 @@ smb_ssnsetup_spnego(struct smb_ctx *ctx, struct mbdata *hint_mb) } } - /* NULL output indicates last call. */ + /* + * Only get here via break in the err==0 case above, + * so we're finalizing a successful session setup. + * + * NULL output token here indicates the final call. + */ (void) ssp_ctx_next_token(ctx, &recv_mb, NULL); /* |