Monday, December 29, 2014

windows start-script for applications

I wrote a WCF service (started as command line application) and had the problem that it needs to be started with admin privileges. So I wrote a dos-script that can either start the server and/or the client and checks the privileges in the first place. Writing a dos script was a little bit like time traveling for me, but finally I managed and understood it. Here my findings:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@echo off
echo _________________________________________________
echo.
echo            HERE A FANCY SERVICENAME
echo _________________________________________________
net session >nul 2>nul
if %errorLevel% equ 0 (
   echo Success: Administrative permissions confirmed.
) else (
   echo Failure: Current permissions inadequate.
   goto end
)
echo.
echo.
set /P startServer=Should the server be started? (y/n) 
set /P startClient=Should the client be started? (y/n) 

IF /I "%startServer%"=="y" (
  echo starting server
  start cmd /c "Server.exe"
) else (
  echo starting server skipped
)

IF /I "%startClient%"=="y" (
  echo starting client
  start cmd /c "Client.exe"
) else (
  echo starting client skipped
)

:end


  • line #1 calls a "hidden from dos-box" action (using @) and disables the printing of the actual commands (only the result of the call will be displayed, but not the call).
  • optionally here a title can be set (using dos: title FANCYNAME) or clearing the screen can be done using command cls
  • following lines show a header
  • then there is a little hack by calling net session. There is no need to understand what this command is doing. The only important information is, that it quits with error 5 (access denied) if you are not currently running in admin-mode. Standard output stream and error output stream will be redirected to nul (to nowhere), so that the only effect is that the errorcode is set to 5 (failed to call the application) or 0 (everything worked fine). 
  • line #7: The errorlevel is a pre-defined variable set by the return code of the previous application. (Unluckily I am not sure if successful applications always reset this variable properly to zero. If you want to be sure then use the command "set" to overwrite the value to zero).
  • the following shows success or error message and jumps on error to the label in line 32 what means that the script stops there.
  • echo. prints an empty row. echo without . shows whether the echo-ing is on or no (as disabled in line #1).
  • set /P requests the console to read from standard in and to write the result to the variable.
  • now we can check for the inputted values (/I for case-insensitive). The 2 equal-signs are similar to equ, but refer to text equality and not to numeric equality
  • start calls an application run in its own dos-box what is a metaphor for run asynchronously without checking the return value or %errorlevel%. I started an own command prompt and call the command with /c parmeter.
pitfalls: 
  • the brackets work exactly the way they were shown above. Separation to own lines are not only forbidden, the script simply doesn't work anymore. 
  • if the server needs some time to startup and the client should be called a few seconds later, then it is a good trick to use a ping localhost (normally 4 seconds for standard 4 packets) to "waste" some time. (start cmd /c "ping localhost >nul 2>nul && Client.exe) Another solution is the command "timeout" what seams appropriate to.

cheers,
Daniel

Tuesday, December 16, 2014

ASP.NET developer efficiency

... because I was asked how to develop asp.net faster... here my top 10 shortcuts which boosted my work (in vs-studio 2013 using the standard key mapping for c# developers)

  1. press ctrl + "," to move between files
  2. press f12 to go to definition
  3. press ctrl k+r for find all references
  4. press f8 to move in the list of found items
  5. press ctrl+shift+b to compile
  6. press ctrl + "-" to jump back in history (regarding cursor position)
  7. press ctrl + alt + p to attach to process (w3wp for iis hosted asp.net) and type the name of the process
  8. press ctrl + shift + f to find stuff / h to replace
  9. press ctrl + "." to add references, implement interfaces and stuff
  10. press alt+tab to jump to browser, f5 for refresh (sorry for mentioning that :-) ).

cheers, Daniel

Thursday, December 11, 2014

nullpointerexception - history

... because today my program won 1:0 against me by raising a nullpointerexception I was willing to check out who invented the null pointer.

So thank you Mr. Tony Hoare, thank you very much! Built in 1965 for "algol w".
His quote: "I call it my billion dollar mistake". 
I would advice him to count that in hours of searching and not in dollars...


kind regards,
Daniel

Tuesday, December 2, 2014

kill only connections of a concrete DB

Today I had the problem that in a dead-lock situation a colleague (responsible for a database on my db server) wanted to fix the situation himself. While using activity monitor he found out which process (more or less equals to connection) was responsible for the fault-situation and wanted to set up a kill statement.

For activity monitor he needed the rights ( http://msdn.microsoft.com/en-us/library/ms175518.aspx ):

  • VIEW SERVER STATE

    and
  • CREATE DATABASE, 
  • ALTER ANY DATABASE, or 
  • VIEW ANY DEFINITION 
Long story short he was not allowed to call kill and I was quite happy about it, because it makes sense that a data owner is not allowed to kill processes of other unrelated services. In fact to kill his own processes could also be accomplished by restarting the corresponding server application, so he seems to have some kind of power anyway. I liked to hear, that I hadn't have to get in touch with the process search, so I needed to enable process killing. My problem was how to secure the whole system against other kill requests and still offer the functionality. 

Some research later I found the concept of impersonation (execute as), but I couldn't imagine how. I tried to allow the user (who failed to kill processes) to switch its user context to a more privileged user. Nothing won, because he is still able to do what he likes. So I created a stored procedure which encapsulates this logic (-> security by obscurity... if you don't know you can switch, you wouldn't try it). Better, but not good enough, because the source of the stored procedure definition was readable, so it is easy to understand which execute as statements has to be executed to become privileged and a security issue (as good as worst case). I tried a lot using master DB, other schemas and so on and found in the end the following link.


... with 5 golden rules which in fact really worked for me. 

  1. We create a new database and set the TRUSTWORTHY flag on
  2. We create a login with the permissions we want
  3. Set the login as the owner of the new database
  4. We create a stored procedure that does the work we want within the new database.
  5. We add the EXECUTE AS OWNER clause to the SP
These were really good tips and finally it worked to impersonate the execution! I just had to hard code the database name which the executor is allowed to kill (in the following code snippet DBNAME1) and check whether the - now - reachable sysprocesses table has an entry with passed in spid and hard coded database.



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
   if(  exists (select 
  * 
  from master.sys.sysprocesses sproc
  where db_name(dbid) = 'DBNAME1' and 
  sproc.spid = @kill_spid)) 
   begin
 
 print 'resolved as DBNAME1 connection ... connection will be killed';
 SET @KillStmt = 'kill ' + CAST(@kill_spid AS VARCHAR(50)) + ''
 PRINT @KillStmt
 
 EXECUTE(@KillStmt)

   end else begin
 
 print 'connection was not established to DBNAME1 ... request will be ignored';

   end

kind regards,
Daniel