naviserver / naviserver (http://naviserver.sf.net/)

fork of aolserver-40x

NaviServer is a high performance web server written in C and Tcl. It can be easily extended in either language to create interesting web sites and services.

Clone this repository (size: 9.7 MB): HTTPS / SSH
$ hg clone http://bitbucket.org/naviserver/naviserver/
commit 2182: db905915ea2a
parent 2181: 8008af67c9c2
branch: default
Added .htaccess mode for nsperm module. Similar to Apache but only to allow access. This is disabled by default, can be enabled in the ns/server/servername/module/nsperm section. Doc is updated. In this version only current directory is checked for .htaccess file.
Vlad Seryakov / vseryakov
13 months ago

Changed (Δ5.8 KB):

raw changeset »

doc/src/module-nsperm.man (25 lines added, 0 lines removed)

doc/src/ns_perm.man (35 lines added, 0 lines removed)

nsperm/Makefile (1 lines added, 1 lines removed)

nsperm/htaccess.tcl (156 lines added, 0 lines removed)

nsperm/nsperm.c (11 lines added, 5 lines removed)

Up to file-list doc/src/module-nsperm.man:

@@ -422,4 +422,29 @@ specified in either of these forms:
422
422
423
423
[list_end]
424
424
425
[section {.htaccess Mode}]
426
427
This mode is similar to Apache but more simpler and limited in functionality. It supports only
428
allowing and denying access to particualr directory.
429
430
[para]
431
432
To enable this
433
434
[example_begin]
435
ns_section "ns/server/servername/module/nsperm"
436
ns_param   htaccess   true
437
ns_param   passwdfile /usr/local/ns/modules/nsperm/passwd
438
[example_end]
439
440
passwdfile can point to any file, by default it set to default nsperm module password file.
441
442
Now, in the directory where access is wanted, create .htaccess file and add lines like these:
443
444
[example_begin]
445
allow vlad john
446
deny steve
447
[example_end]
448
449
425
450
[manpage_end]

Up to file-list doc/src/ns_perm.man:

@@ -18,6 +18,7 @@ and the specified user text (userfield)
18
18
19
19
[arg -deny] and hostnames are specified, the user will be denied on the specified hostnames.
20
20
The hostname must be specified as ipaddress/netmask or dnshostname.
21
21
22
[example_begin]
22
23
128.2.142.0/255.255.255.0 or www.microsoft.com or .microsoft.com.
23
24
[example_end]
@@ -100,6 +101,40 @@ this command clears the memory first and
100
101
101
102
[list_end]
102
103
104
[section CONFIGURATION]
105
106
The following configuration options are available to control permission module
107
108
[list_begin definitions]
109
110
[def htaccess]
111
112
This parameter if set to true, enables .htaccess mode, similar to what the Apache web server
113
has but very simple and limited in functionality.
114
115
[para]
116
On every request the server looks for .htaccess file in the current request directory and loads it if
117
modified since the last read. The structure of the file is simple:
118
119
[example_begin]
120
allow user ...
121
deny user ...
122
[example_end]
123
124
[def passwdfile]
125
126
This parameter determines which file with users and passwords needs to be checked for modification
127
and reloaded automatically.
128
129
[list_end]
130
131
[example_begin]
132
ns_section "ns/server/servername/module/nsperm"
133
ns_param   htaccess   false
134
ns_param   passwdfile /usr/local/ns/modules/nsperm/passwd
135
[example_end]
136
137
103
138
[section EXAMPLES]
104
139
105
140
[example_begin]

Up to file-list nsperm/Makefile:

33
33
MODNAME  =  nsperm
34
34
MOD      =  nsperm.so
35
35
OBJS     =  nsperm.o
36
TCL      =  init.tcl compat.tcl
36
TCL      =  init.tcl compat.tcl htaccess.tcl
37
37
MODINST	 =  cpfiles
38
38
39
39
include ../include/Makefile.build

Up to file-list nsperm/htaccess.tcl:

1
#
2
# The contents of this file are subject to the Mozilla Public License
3
# Version 1.1 (the "License"); you may not use this file except in
4
# compliance with the License. You may obtain a copy of the License at
5
# http://aolserver.com/.
6
#
7
# Software distributed under the License is distributed on an "AS IS"
8
# basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
9
# the License for the specific language governing rights and limitations
10
# under the License.
11
#
12
# The Original Code is AOLserver Code and related documentation
13
# distributed by AOL.
14
#
15
# The Initial Developer of the Original Code is America Online,
16
# Inc. Portions created by AOL are Copyright (C) 1999 America Online,
17
# Inc. All Rights Reserved.
18
#
19
# Alternatively, the contents of this file may be used under the terms
20
# of the GNU General Public License (the "GPL"), in which case the
21
# provisions of GPL are applicable instead of those above.  If you wish
22
# to allow use of your version of this file only under the terms of the
23
# GPL and not to allow others to use your version of this file under the
24
# License, indicate your decision by deleting the provisions above and
25
# replace them with the notice and other provisions required by the GPL.
26
# If you do not delete the provisions above, a recipient may use your
27
# version of this file under either the License or the GPL.
28
#
29
30
#
31
# $Header$
32
#
33
34
#
35
# modules/nsperm/htaccess.tcl -
36
#   support for .htaccess files
37
#
38
39
proc ns_perm_filter { args } {
40
41
    set url [ns_conn url]
42
43
    # Do not allow to server special files
44
    switch -- [file tail $url] {
45
     .htaccess -
46
     .htpasswd {
47
        returnnotfound
48
        return filter_return
49
     }
50
    }
51
52
    set lock [nsv_get nsperm lock]
53
54
    set dir [ns_url2file $url]
55
    if { [file isdirectory $dir] == 0 } {
56
       set dir [file dirname $dir]
57
       set url [file dirname $url]
58
    }
59
60
    ns_mutex eval $lock {
61
62
      # Load passwd file if changed
63
      ns_perm_load [nsv_get nsperm passwdfile] $url ns_perm_adduser
64
65
      # Load access file if changed
66
      ns_perm_load $dir/.htaccess $url ns_perm_addperm
67
    }
68
69
    return filter_ok
70
}
71
72
proc ns_perm_load { file url callback } {
73
74
    if { [file exists $file] == 0 } {
75
       return
76
    }
77
78
    set mtime [file mtime $file]
79
    if { [nsv_exists nsperm $file] } {
80
       if { $mtime <= [nsv_get nsperm $file] } {
81
          return
82
       }
83
    }
84
85
    ns_log Notice ns_perm_load: $file: $url $callback
86
87
    if { [catch {
88
      foreach line [split [ns_fileread $file] "\n"] {
89
        $callback $file $url [split $line " :"]
90
      }
91
    } errmsg] } {
92
      ns_log Error ns_perm_load: $file: $errmsg
93
    }
94
95
    nsv_set nsperm $file $mtime
96
}
97
98
proc ns_perm_adduser { file url line } {
99
100
    if { [llength $line] < 2 } {
101
       return
102
    }
103
104
    set clear ""
105
    set user [lindex $line 0]
106
    set passwd [lindex $line 1]
107
108
    if { $user == "" || $passwd == "" } {
109
       return
110
    }
111
112
    ns_perm deluser $user
113
114
    if { [string range $passwd 0 1] != "CU" } {
115
       ns_perm adduser -clear $user $passwd ""
116
    } else {
117
       ns_perm adduser $user $passwd ""
118
    }
119
}
120
121
proc ns_perm_addperm { file url line } {
122
123
    set op [lindex $line 0]
124
    if { $op != "allow" && $op != "deny" } {
125
       return
126
    }
127
128
    # Without users we clear the whole directory from any permissions
129
    if { [lindex $line 1] == "" } {
130
       ns_perm delperm GET $url
131
       ns_perm delperm POST $url
132
    }
133
134
    eval ns_perm ${op}user GET $url [lrange $line 1 end]
135
    eval ns_perm ${op}user POST $url [lrange $line 1 end]
136
137
    # Make sure empty user is not allowed, default passwd contains
138
    # user with no name to support implicit allow mode (Why!?)
139
    ns_perm denyuser GET $url ""
140
    ns_perm denyuser POST $url ""
141
}
142
143
ns_runonce {
144
145
   set path ns/server/[ns_info server]/module/nsperm
146
147
   if { [ns_config -bool $path htaccess 0] } {
148
      nsv_set nsperm lock [ns_mutex create]
149
      nsv_set nsperm passwdfile [ns_config $path passwdfile [file join [ns_info home] modules nsperm passwd]]
150
      ns_register_filter preauth GET /* ns_perm_filter
151
152
      ns_log Notice nsperm: enabling .htaccess support
153
   }
154
155
}
156

Up to file-list nsperm/nsperm.c:

@@ -518,7 +518,9 @@ static int AuthProc(char *server, char *
518
518
519
519
    /*
520
520
     * Checks above failed.  If implicit allow is not set,
521
     * change the status back to unauthorized.
521
     * change the status back to unauthorized. This flag will be set only when
522
     * at least one deny user was added to the the permission record, otherwise
523
     * it will allow user with name "" to pass. What a nonsense!
522
524
     */
523
525
524
526
    if (!(permPtr->flags & PERM_IMPLICIT_ALLOW)) {
@@ -1343,27 +1345,31 @@ static void WalkCallback(Tcl_DString * d
1343
1345
    Tcl_HashSearch search;
1344
1346
    Tcl_HashEntry *hPtr;
1345
1347
1348
    if (permPtr->flags & PERM_IMPLICIT_ALLOW) {
1349
        Ns_DStringAppend(dsPtr, " -implicitallow ");
1350
    }
1351
1346
1352
    hPtr = Tcl_FirstHashEntry(&permPtr->allowuser, &search);
1347
1353
    while (hPtr != NULL) {
1348
        Ns_DStringVarAppend(dsPtr, " -allowuser ", Tcl_GetHashKey(&permPtr->allowuser, hPtr), NULL);
1354
        Ns_DStringVarAppend(dsPtr, " -allowuser {", Tcl_GetHashKey(&permPtr->allowuser, hPtr), "}", NULL);
1349
1355
        hPtr = Tcl_NextHashEntry(&search);
1350
1356
    }
1351
1357
1352
1358
    hPtr = Tcl_FirstHashEntry(&permPtr->denyuser, &search);
1353
1359
    while (hPtr != NULL) {
1354
        Ns_DStringVarAppend(dsPtr, " -denyuser ", Tcl_GetHashKey(&permPtr->denyuser, hPtr), NULL);
1360
        Ns_DStringVarAppend(dsPtr, " -denyuser {", Tcl_GetHashKey(&permPtr->denyuser, hPtr), "}", NULL);
1355
1361
        hPtr = Tcl_NextHashEntry(&search);
1356
1362
    }
1357
1363
1358
1364
    hPtr = Tcl_FirstHashEntry(&permPtr->allowgroup, &search);
1359
1365
    while (hPtr != NULL) {
1360
        Ns_DStringVarAppend(dsPtr, " -allowgroup ", Tcl_GetHashKey(&permPtr->allowgroup, hPtr), NULL);
1366
        Ns_DStringVarAppend(dsPtr, " -allowgroup {", Tcl_GetHashKey(&permPtr->allowgroup, hPtr), "}", NULL);
1361
1367
        hPtr = Tcl_NextHashEntry(&search);
1362
1368
    }
1363
1369
1364
1370
    hPtr = Tcl_FirstHashEntry(&permPtr->denygroup, &search);
1365
1371
    while (hPtr != NULL) {
1366
        Ns_DStringVarAppend(dsPtr, " -denygroup ", Tcl_GetHashKey(&permPtr->denygroup, hPtr), NULL);
1372
        Ns_DStringVarAppend(dsPtr, " -denygroup {", Tcl_GetHashKey(&permPtr->denygroup, hPtr), "}", NULL);
1367
1373
        hPtr = Tcl_NextHashEntry(&search);
1368
1374
    }
1369
1375
}