/* Prompt for a password and set it on the SMB context. */ static Boolean SMBPasswordPrompt( SMBHANDLE hConnection, uint64_t options) { void * hContext = NULL; NTSTATUS status; char * passwd; char passbuf[SMB_MAXPASSWORDLEN + 1]; char prompt[128]; /* They told us not to prompt */ if (options & kSMBOptionNoPrompt) return false; status = SMBServerContext(hConnection, &hContext); if (!NT_SUCCESS(status)) { return false; } /* * If the password is already set, don't prompt. Since anonymous and guest * both have an empty password this will protect us from prompting in * those cases. */ if (((struct smb_ctx *)hContext)->ct_flags & SMBCF_EXPLICITPWD) { return false; } /* * If the target hasn't set a user name, let's assume that we should use * the current username. This is almost always what the caller wants, when * being prompted for a password. The above check protect us from overriding * anonymouse connections. */ if (((struct smb_ctx *)hContext)->ct_setup.ioc_user[0] == '\0') { struct passwd * pwent; pwent = getpwuid(geteuid()); if (pwent) { smb_ctx_setuser(hContext, pwent->pw_name); } } snprintf(prompt, sizeof(prompt), "Password for %s: ", ((struct smb_ctx *)hContext)->serverName); /* If we have a TTY, read a password and retry ... */ passwd = readpassphrase(prompt, passbuf, sizeof(passbuf), RPP_REQUIRE_TTY); if (passwd) { smb_ctx_setpassword(hContext, passwd, TRUE); memset(passbuf, 0, sizeof(passbuf)); } return true; }
/* * level values: * 0 - default * 1 - server * 2 - server:user * 3 - server:user:share */ static int smb_ctx_readrcsection(struct smb_ctx *ctx, const char *sname, int level) { char *p; int error; if (level >= 0) { rc_getstringptr(smb_rc, sname, "charsets", &p); if (p) { error = smb_ctx_setcharset(ctx, p); if (error) smb_error("charset specification in the section '%s' ignored", error, sname); } } if (level <= 1) { rc_getint(smb_rc, sname, "timeout", &ctx->ct_ssn.ioc_timeout); rc_getint(smb_rc, sname, "retry_count", &ctx->ct_ssn.ioc_retrycount); } if (level == 1) { rc_getstringptr(smb_rc, sname, "addr", &p); if (p) { error = smb_ctx_setsrvaddr(ctx, p); if (error) { smb_error("invalid address specified in the section %s", 0, sname); return error; } } } if (level >= 2) { rc_getstringptr(smb_rc, sname, "password", &p); if (p) smb_ctx_setpassword(ctx, p); } rc_getstringptr(smb_rc, sname, "workgroup", &p); if (p) smb_ctx_setworkgroup(ctx, p); return 0; }
/* * Verify context before connect operation(s), * lookup specified server and try to fill all forgotten fields. */ int smb_ctx_resolve(struct smb_ctx *ctx) { struct smbioc_ossn *ssn = &ctx->ct_ssn; struct smbioc_oshare *sh = &ctx->ct_sh; struct nb_name nn; struct sockaddr *sap; struct sockaddr_nb *salocal, *saserver; char *cp; u_char cstbl[256]; u_int i; int error = 0; ctx->ct_flags &= ~SMBCF_RESOLVED; if (ssn->ioc_srvname[0] == 0) { smb_error("no server name specified", 0); return EINVAL; } if (ssn->ioc_user[0] == 0) { smb_error("no user name specified for server %s", 0, ssn->ioc_srvname); return EINVAL; } if (ctx->ct_minlevel >= SMBL_SHARE && sh->ioc_share[0] == 0) { smb_error("no share name specified for %s@%s", 0, ssn->ioc_user, ssn->ioc_srvname); return EINVAL; } error = nb_ctx_resolve(ctx->ct_nb); if (error) return error; if (ssn->ioc_localcs[0] == 0) strcpy(ssn->ioc_localcs, "default"); /* XXX: locale name ? */ error = smb_addiconvtbl("tolower", ssn->ioc_localcs, nls_lower); if (error) return error; error = smb_addiconvtbl("toupper", ssn->ioc_localcs, nls_upper); if (error) return error; if (ssn->ioc_servercs[0] != 0) { for(i = 0; i < sizeof(cstbl); i++) cstbl[i] = i; nls_mem_toext(cstbl, cstbl, sizeof(cstbl)); error = smb_addiconvtbl(ssn->ioc_servercs, ssn->ioc_localcs, cstbl); if (error) return error; for(i = 0; i < sizeof(cstbl); i++) cstbl[i] = i; nls_mem_toloc(cstbl, cstbl, sizeof(cstbl)); error = smb_addiconvtbl(ssn->ioc_localcs, ssn->ioc_servercs, cstbl); if (error) return error; } if (ctx->ct_srvaddr) { error = nb_resolvehost_in(ctx->ct_srvaddr, &sap); } else { error = nbns_resolvename(ssn->ioc_srvname, ctx->ct_nb, &sap); } if (error) { smb_error("can't get server address", error); return error; } nn.nn_scope = ctx->ct_nb->nb_scope; nn.nn_type = NBT_SERVER; strcpy(nn.nn_name, ssn->ioc_srvname); error = nb_sockaddr(sap, &nn, &saserver); nb_snbfree(sap); if (error) { smb_error("can't allocate server address", error); return error; } ssn->ioc_server = (struct sockaddr*)saserver; if (ctx->ct_locname[0] == 0) { error = nb_getlocalname(ctx->ct_locname); if (error) { smb_error("can't get local name", error); return error; } nls_str_upper(ctx->ct_locname, ctx->ct_locname); } strcpy(nn.nn_name, ctx->ct_locname); nn.nn_type = NBT_WKSTA; nn.nn_scope = ctx->ct_nb->nb_scope; error = nb_sockaddr(NULL, &nn, &salocal); if (error) { nb_snbfree((struct sockaddr*)saserver); smb_error("can't allocate local address", error); return error; } ssn->ioc_local = (struct sockaddr*)salocal; ssn->ioc_lolen = salocal->snb_len; ssn->ioc_svlen = saserver->snb_len; if (ssn->ioc_password[0] == 0 && (ctx->ct_flags & SMBCF_NOPWD) == 0) { cp = getpass("Password:"); error = smb_ctx_setpassword(ctx, cp); if (error) return error; } ctx->ct_flags |= SMBCF_RESOLVED; return 0; }