This blog contains Matt's ramblings about Business Productivity and Information/Knowledge Worker solutions, Cloud, Social Media and other technology stuff. Will also include a bit of Carp fishing ;) It's not updated as frequently as it used to be because, putting it simply, there are more important priorities in life.
Wednesday, 20 July 2005
WSS3 search errors
Solution: Create a site collection at root. See: http://support.microsoft.com/default.aspx?scid=kb;en-us;936914&sd=rss&spid=12200
Scope: This is only applicable to WSS, although may also apply to MOSS in certain scenarios... This prevents the use of WSS site collections on managed paths with non-SP (i.e.; standalone ASPX) content at the root, well, at least without slapping ISA in the mix to manage the pathing...
Monday, 9 May 2005
Password changing for free!
This “webpart” adds password change functionality to SharePoint, enabling remote users to control their password even if they can’t do a local logon.
USE AT YOUR OWN RISK
This has been tested in a small server farm and a single server farm, both in a AD (2003) environment, it should also work in any SharePoint farm, in a AD (2000 or 2003) environment.
It might work in a standalone SharePoint deployment (ie; no AD), but this is not tested…
It has been tested using both Integrated and Basic authentication to SharePoint (and the iisadmpwd virtual directory). Both authentication modes have been tested logging in from a remote source (non-domain member) using “DOMAIN\Username”, UPN (where multiple UPN suffixes have been configured in ADDT) and straight “username” using Basic authentication. Obviously, basic auth is not recommended for non-SSL implementations as
passwords will be sent in clear.
Installation and Configuration steps 1-9 will need to be repeated on each front-end server in a SharePoint farm with multiple (NLB or otherwise) frontend servers…
Appendices A & B are the source code change required to the asp pages
Installation and Configuration
1. Enable IIS Password changing (follow MSKB-555071)
a. If the site is not running on HTTPS make sure you set the value to 1 when you run: “adsutil.vbs set w3svc/1/PasswordChangeFlags [value]”
b. Ensure the iisadmpwd virtual directory is running under the same AppPool as SharePoint
2. Add the Iisadmpwd virtual directory as an excluded managed path in SharePoint
3. In ADUC, delegate the “read user information” and “reset user password” permission to the account running the SharePoint AppPool
4. Test that password changing works by opening http://server_name/iisadmpwd/aexp2b.asp in your browser
a. Resolve any problems found before continuing!
5. Browse to C:\WINDOWS\system32\inetsrv\iisadmpwd\ on the Front-end server
6. Edit “aexp2b.asp” in a text editor (after making a backup copy)
a. Paste in the code found in Appendix A of this document
b. Save the file
7. Edit “text.asp” in a text editor (after making a backup copy)
a. Change the value of “L_BackTo_Text” to: "Return to Intranet home"
b. Change the value of “L_PasswordToShort_Text” to reflect the password requirements of the domain (min length, complexity etc)
c. Make any further display name changes required
d. Save the file
8. Edit “achg.asp” in a text editor (after making a backup copy)
a. Paste in the code found in Appendix B of this document
b. Save the file
9. Change the file extension of all other asp pages in the directory to something other than “asp” (this increases the security of the password change system)
10. Add a “Page Viewer” webpart to the Area/Site of your choice and give the URL as “../../../../iisadmpwd/aexp2b.asp”
11. Change the title of the webpart as required
12. Give the webpart a fixed height of 250 pixels
13. Apply these changes
14. The webpart will display the password change boxes with the domain and username fields being RO, and the fonts/styles matching the rest of your
Area/Site
Appendix A
<%@Language="VBSCRIPT"%><HTML><!--#include file = "text.asp"--><title><%=L_Title_Text%></title><FONT COLOR=FFFFFF><STYLE></STYLE></FONT><head><META HTTP-EQUIV="Content-Type" Content="text/html; charset=Windows-1252"><link rel="stylesheet" type="text/css" href="/_layouts/1033/styles/ows.css"><link rel="stylesheet" type="text/css" href="/_layouts/1033/styles/menu.css"><link rel="stylesheet" type="text/css" href="/_layouts/1033/styles/sps.css"></head><BODY BGCOLOR=#FFFFFF LINK=000000 VLINK=000000><%On Error goto 0if Request.Form("cancel") <> "" thenResponse.Redirect(Request.QueryString)end ifdim domain, username, posbs, posatusername = Request.Form("acct")if username <> "" thenusername = Server.HTMLEncode(username)elseusername = Server.HTMLEncode(Request.ServerVariables("REMOTE_USER"))end ifdomain = Request.Form("domain")if domain <> "" thendomain = Server.HTMLEncode(domain)elseposbs = Instr(1, username, "\")posat = Instr(1, username, "@")if posbs > 0 thendomain = Left(username, posbs - 1)username = Right(username, len(username) - posbs)elseif posat > 0 thendomain = Right(username, len(username) - posat)username = Left(username, posat - 1)elseset nw = Server.CreateObject("WScript.Network")domain = nw.UserDomainend ifend if%><!-- Windows NT Server with IIS --><%if Instr(1,Request.ServerVariables("SERVER_SOFTWARE"), "IIS") > 0 then%><!--
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0><TR VALIGN=CENTER><TD></TD><TD WIDTH=20> </TD><TD><FONT SIZE=+3 COLOR=#000000><B><%=L_ISM_Text%><BR> <FONT SIZE=-1><%=L_IIS6_Text%><FONT></B></FONT></TD></TR></Table>--><%end if%><!-- Windows NT Workstation with PWS --><%if Instr(1,Request.ServerVariables("SERVER_SOFTWARE"), "PWS") then%><!--
<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0><TR VALIGN=CENTER><TD></TD><TD WIDTH=20> </TD><TD><FONT SIZE=+3 COLOR=#000000><B><%=L_ISM_Text%><BR> <FONT SIZE=-1><%=L_PWS_Text%><FONT></B></FONT></TD></TR></Table>--><%end if%><p><form method="POST"action="http://<%=Server.HTMLEncode(Request.ServerVariables("SERVER_NAME"))%>/iisadmpwd/achg.asp?<%=Server.HTMLEncode(Request.QueryString)%>"><table><tr><td><%=L_Domain_Text%></td><td><input type="text" name="domain" READONLY value="<%Response.Write domain%>"%Response.Write domain%>"></td></tr><tr><td><%=L_Account_Text%></td><td><input type="text" name="acct" READONLY value="<%Response.Write username%>"%Response.Write username%>"></td></tr><tr><td><%=L_OldPassword_Text%></td><td><input type="password" name="old" value=""></td></tr><tr><td><%=L_NewPassword_Text%></td><td><input type="password" name="new" value=""></td></tr><tr><td><%=L_Confirm_Text%></td><td><input type="password" name="new2" value=""></td></tr></table><p><input type="submit" value="<%=L_OK_Text%>"><input type="submit" name="cancel" value="<%=L_Cancel_Text%>"><input type="reset" value="<%=L_Reset_Text%>"></form></body></html>
Appendix B
<%@Language="VBScript"%><HTML><!--#include file = "text.asp"--><title><%=L_Title_Text%></title><STYLE></STYLE><head><META HTTP-EQUIV="Content-Type" Content="text/html; charset=Windows-1252"><link rel="stylesheet" type="text/css" href="/_layouts/1033/styles/ows.css"><link rel="stylesheet" type="text/css" href="/_layouts/1033/styles/menu.css"><link rel="stylesheet" type="text/css" href="/_layouts/1033/styles/sps.css"></head><BODY BGCOLOR=#FFFFFF LINK=000000 VLINK=000000><%On Error goto 0%><%if Request.Form("cancel") <> "" thenif Request.Form("denyifcancel") <> "" thenResponse.Status = "401 Unauthorized"Response.EndelseResponse.Redirect(Request.QueryString)end ifResponse.Endend if%><!-- Windows NT Server with IIS --><%if Instr(1,Request.ServerVariables("SERVER_SOFTWARE"), "IIS") > 0 then%><!--<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0><TR VALIGN=CENTER><TD></TD><TD WIDTH=20> </TD><TD><FONT SIZE=+3 COLOR=#000000><B><%=L_ISM_Text%><BR> <FONT SIZE=-1><%=L_IIS6_Text%><FONT></B></FONT></TD></TR></Table>--><%end if%><!-- Windows NT Workstation with PWS --><%if Instr(1,Request.ServerVariables("SERVER_SOFTWARE"), "PWS") then%><!--<TABLE BORDER=0 CELLPADDING=0 CELLSPACING=0><TR VALIGN=CENTER><TD></TD><TD WIDTH=20> </TD><TD><FONT SIZE=+3 COLOR=#000000><B><%=L_ISM_Text%><BR> <FONT SIZE=-1><%=L_PWS_Text%><FONT></B></FONT></TD></TR></Table>--><%end if%><p><%if Request.Form("new") <> Request.Form("new2") then %><%=L_PWDM_Text%><p><%Response.Write "<br><H3><a href=" &Server.HTMLEncode(Request.ServerVariables("HTTP_REFERER")) & ">" & L_Back_Text & " </a></H3>"Response.End%><%end if%><%On Error resume nextdim domain, posbs, posat, username, pUser, rootdim upn_nameupn_name = ""domain = Trim(Request.Form("domain"))' if no domain is present we try to get the domain from the username,' e.g. domainusername or praesi@ultraschallpiloten.comif domain = "" thenposbs = Instr(1,Request.Form("acct"),"\" )posat = Instr(1,Request.Form("acct"),"@" )if posbs > 0 thendomain = Left(Request.Form("acct"),posbs-1)username = Right(Request.Form("acct"),len(Request.Form("acct")) - posbs)elseif posat > 0 thenupn_name = Request.Form("acct")domain = Right(upn_name, len(upn_name) - posat)username = Left(upn_name, posat-1)elseusername = Request.Form("acct")set nw = Server.CreateObject("WScript.Network")domain = nw.Computernameend ifelseusername = Trim(Request.Form("acct"))end if' verify that the characters in the user name are validif IsInvalidUsername(username) = true thenResponse.Write L_InvalidUsername_Text & "."Response.Write "<br><H3><a href=" &Server.HTMLEncode(Request.ServerVariables("HTTP_REFERER")) & ">" & L_Back_Text & " </a></H3>"Response.Endend if' verify that the characters in the domain name are validif IsInvalidDomainname(domain) = true thenResponse.Write L_InvalidDomainname_Text & "."Response.Write "<br><H3><a href=" &Server.HTMLEncode(Request.ServerVariables("HTTP_REFERER")) & ">" & L_Back_Text & " </a></H3>"Response.Endend ifif upn_name = "" thenset pUser = GetObject("WinNT://" & domain & "/" & username & ",user")if Not IsObject(pUser) thenset root = GetObject("WinNT:")set pUser = root.OpenDSObject("WinNT://" & domain & "/" & username & ",user",username, Request.Form("old"),1)Response.Write "<!--OpenDSObject call-->"end ifif Not IsObject(pUser) thenset pUser = Server.CreateObject("IIS.PwdChg")pUser.Domain = domainpUser.User = usernameend ifelseset pUser = Server.CreateObject("IIS.PwdChg")if Not IsObject(pUser) thenset pUser = GetObject("WinNT://" & domain & "/" & username & ",user")if Not IsObject(pUser) thenset root = GetObject("WinNT:")set pUser = root.OpenDSObject("WinNT://" & domain & "/" & username &",user", username, Request.Form("old"),1)Response.Write "<!--OpenDSObject call-->"end ifelsepUser.Domain = domainpUser.User = usernamepUser.UPN = upn_nameend ifend ifif Not IsObject(pUser) then'Response.Write "domain <> null - OpenDSObject also failed"if err.number = -2147024843 thenResponse.Write L_NotExist_Text & "."elseif err.description <> "" thenResponse.Write L_Error_Text & ": " & err.descriptionelseResponse.Write L_Errornumber_Text & ": " & err.numberend ifResponse.Write "<br><H3><a href=" &Server.HTMLEncode(Request.ServerVariables("HTTP_REFERER")) & ">" & L_Back_Text & " </a></H3>"end ifResponse.Endend iferr.ClearpUser.ChangePassword Request.Form("old"), Request.Form("new")if err.number <> 0 thenif err.number = -2147024810 thenResponse.Write "<p>" & L_Error_Text & ": " & L_Invalid_Textelseif err.number = -2147022651 thenResponse.Write L_PasswordToShort_TextelseResponse.Write L_Errornumber_Text & ": " & err.numberend ifResponse.Write "<br><H3><a href=" &Server.HTMLEncode(Request.ServerVariables("HTTP_REFERER")) & ">" & L_Back_Text & " </a></H3>"Response.EndelseResponse.Write L_PasswordChanged_Text & ".<p>"end if%><br><a href="http://<%=Server.HTMLEncode(Request.ServerVariables("SERVER_NAME"))%>/"target="_top"><%=L_BackTo_Text%></a></body></html><%function IsInvalidUsername(username)dim reset re = new RegExp' list of invalid characters in a user name.re.Pattern = "[/\\""\[\]:<>\+=;,@]"IsInvalidUsername = re.Test(username)end functionfunction IsInvalidDomainname(domainname)dim reset re = new RegExp' list of invalid characters in a domain name.re.Pattern = "[/\\""\[\]:<>\+=;,@!#$%^&\(\)\{\}\|~]"IsInvalidDomainName = re.Test(domainname)end function%>