summaryrefslogtreecommitdiffstats
path: root/heartbeat/smb-share.in
blob: 8a1a0a860469da486679f32d20f64914af9724bb (plain)
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
#!@BASH_SHELL@
#
#       OCF Resource Agent for create samba config snippets.
#
#
#
#     Copyright (c) 2021 B1 Systems GmbH <info@b1-systems.de>
#                            Author:
#       Tobias D. Oestreicher <oestreicher@b1-systems.de>
#                    All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it would be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# Further, this software is distributed without any warranty that it is
# free of the rightful claim of any third person regarding infringement
# or the like.  Any license provided herein, whether implied or
# otherwise, applies only to this software file.  Patent licenses, if
# any, provided herein do not apply to combinations of this program with
# other software, or any other product whatsoever.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
#
#
#
#       OCF parameters are as below:
#         OCF_RESKEY_outfile
#         OCF_RESKEY_includesfile
#         OCF_RESKEY_confd
#         OCF_RESKEY_share
#         OCF_RESKEY_path
#         OCF_RESKEY_hosts_allow
#         OCF_RESKEY_browseable
#         OCF_RESKEY_writeable
#         OCF_RESKEY_read_only
#         OCF_RESKEY_guest_ok
#         OCF_RESKEY_directory_mask
#         OCF_RESKEY_create_mask
#         OCF_RESKEY_printable
#         OCF_RESKEY_valid_users
#         OCF_RESKEY_force_user
#         OCF_RESKEY_force_group
#         OCF_RESKEY_extraopt
#         OCF_RESKEY_extraopt_list
#
#######################################################################

#######################################################################
#
# Purpose:
# --------
# This RA is used to control samba shares on the fly.
# For adding and removing samba shares no restart of the samba daemon 
# is needed. This is the equivalent of the exportfs RA which is used
# for nfs shares.
#
# How to use:
# -----------
# For this RA to work as expected you need a cloned samba daemon which
# have to be startet before.
# After this RA manages config snippets placed in the filesystem and
# after a fence of that node these snippets will still located there
# you will have to use a tmpfs mount for this.
# Also you need a basic smb.conf file in which all global parameters an 
# permanent shares should be placed.
# Within this smb.conf also you must put a line in the global section
# like this:
#
#     include = /etc/samba/conf.d/pacemaker-includes.conf
#
# The filename can be changed by setting the parameter "includesfile".
# Every share created by this RA will create a new file located in:
#
#     /etc/samba/conf.d/
#
# This directory also can be changed by setting the RA parameter "confd".
#
#######################################################################

# Initialization:

: ${OCF_FUNCTIONS_DIR=${OCF_ROOT}/lib/heartbeat}
. ${OCF_FUNCTIONS_DIR}/ocf-shellfuncs

# Defaults

OCF_RESKEY_outfile_default=""
OCF_RESKEY_includesfile_default="/etc/samba/conf.d/pacemaker-includes.conf"
OCF_RESKEY_confd_default="/etc/samba/conf.d"
OCF_RESKEY_share_default=""
OCF_RESKEY_path_default=""
OCF_RESKEY_hosts_allow_default=""
OCF_RESKEY_browseable_default=""
OCF_RESKEY_writeable_default=""
OCF_RESKEY_read_only_default=""
OCF_RESKEY_guest_ok_default=""
OCF_RESKEY_directory_mask_default=""
OCF_RESKEY_create_mask_default=""
OCF_RESKEY_printable_default=""
OCF_RESKEY_valid_users_default=""
OCF_RESKEY_force_user_default=""
OCF_RESKEY_force_group_default=""
OCF_RESKEY_extraopt_default=""
OCF_RESKEY_extraopt_list_default=""


: ${OCF_RESKEY_outfile=${OCF_RESKEY_outfile_default}}
: ${OCF_RESKEY_includesfile=${OCF_RESKEY_includesfile_default}}
: ${OCF_RESKEY_confd=${OCF_RESKEY_confd_default}}
: ${OCF_RESKEY_share=${OCF_RESKEY_share_default}}
: ${OCF_RESKEY_path=${OCF_RESKEY_path_default}}
: ${OCF_RESKEY_hosts_allow=${OCF_RESKEY_hosts_allow_default}}
: ${OCF_RESKEY_browseable=${OCF_RESKEY_browseable_default}}
: ${OCF_RESKEY_writeable=${OCF_RESKEY_writeable_default}}
: ${OCF_RESKEY_read_only=${OCF_RESKEY_read_only_default}}
: ${OCF_RESKEY_guest_ok=${OCF_RESKEY_guest_ok_default}}
: ${OCF_RESKEY_directory_mask=${OCF_RESKEY_directory_mask_default}}
: ${OCF_RESKEY_create_mask=${OCF_RESKEY_create_mask_default}}
: ${OCF_RESKEY_printable=${OCF_RESKEY_printable_default}}
: ${OCF_RESKEY_valid_users=${OCF_RESKEY_valid_users_default}}
: ${OCF_RESKEY_force_user=${OCF_RESKEY_force_user_default}}
: ${OCF_RESKEY_force_group=${OCF_RESKEY_force_group_default}}
: ${OCF_RESKEY_extraopt=${OCF_RESKEY_extraopt_default}}
: ${OCF_RESKEY_extraopt_list=${OCF_RESKEY_extraopt_list_default}}

#######################################################################

#######################################################################

meta_data() {
        cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="smb-share" version="1.0">
    <version>1.0</version>
    <longdesc lang="en">
This RA is used to control samba shares on the fly.
For adding and removing samba shares no restart of the samba daemon 
is needed. This is the equivalent of the exportfs RA which is used
for nfs shares.

For this RA to work as expected you need a cloned samba daemon which
have to be startet before.
After this RA manages config snippets placed in the filesystem and
after a fence of that node these snippets will still located there
you will have to use a tmpfs mount for this.
Also you need a basic smb.conf file in which all global parameters an
permanent shares should be placed.
Within this smb.conf also you must put a line in the global section
like this:

     include = /etc/samba/conf.d/pacemaker-includes.conf

The filename can be changed by setting the parameter includesfile.
Every share created by this RA will create a new file located in:

     /etc/samba/conf.d/

This directory also can be changed by setting the RA parameter confd.
    </longdesc>
    <shortdesc lang="en">Manages samba shares on the fly</shortdesc>

    <parameters>

        <parameter name="share" unique="1" required="1">
            <longdesc lang="en">
            Set the name of a windows share which should be added to Samba
            example name "myshare" resulting in [myshare].
            </longdesc>
            <shortdesc lang="en">sharename</shortdesc>
            <content type="string" default="${OCF_RESKEY_share_default}" />
        </parameter>

        <parameter name="path" unique="1" required="0">
            <longdesc lang="en">
            Set the path to share for cifs clients.
            example path "/srv/data/myshare".
            </longdesc>
            <shortdesc lang="en">path to share</shortdesc>
            <content type="string" default="${OCF_RESKEY_path_default}" />
        </parameter>

        <parameter name="hosts_allow" unique="0" required="0">
            <longdesc lang="en">
            This parameter is a comma, space, or tab delimited set of hosts which are permitted to access a service.
            </longdesc>
            <shortdesc lang="en">hosts allow parameter</shortdesc>
            <content type="string" default="${OCF_RESKEY_hosts_allow_default}" />
        </parameter>

        <parameter name="browseable" unique="0" required="0">
            <longdesc lang="en">
            This controls whether this share is seen in the list of available shares in a net view and in the browse list.
            </longdesc>
            <shortdesc lang="en">browseable parameter</shortdesc>
            <content type="string" default="${OCF_RESKEY_browseable_default}" />
        </parameter>

        <parameter name="writeable" unique="0" required="0">
            <longdesc lang="en">
            Inverted synonym for read only.
            </longdesc>
            <shortdesc lang="en">writeable parameter</shortdesc>
            <content type="string" default="${OCF_RESKEY_writeable_default}" />
        </parameter>
        
        <parameter name="read_only" unique="0" required="0">
            <longdesc lang="en">
            This option can be used to turn the writing backends tdb, tdb2, and ldap into read only mode. 
            This can be useful e.g. in cases where a pre-filled database exists that should not be extended automatically.
            </longdesc>
            <shortdesc lang="en">read only parameter</shortdesc>
            <content type="string" default="${OCF_RESKEY_read_only_default}" />
        </parameter>
        
        <parameter name="guest_ok" unique="0" required="0">
            <longdesc lang="en">
            If this parameter is yes for a service, then no password is required to connect to the service. Privileges will be those of the guest account.
            </longdesc>
            <shortdesc lang="en">guest ok parameter</shortdesc>
            <content type="string" default="${OCF_RESKEY_guest_ok_default}" />
        </parameter>
        
        <parameter name="directory_mask" unique="0" required="0">
            <longdesc lang="en">
            This parameter is the octal modes which are used when converting DOS modes to UNIX modes when creating UNIX directories.
            </longdesc>
            <shortdesc lang="en">directory mask parameter</shortdesc>
            <content type="string" default="${OCF_RESKEY_directory_mask_default}" />
        </parameter>
        
        <parameter name="create_mask" unique="0" required="0">
            <longdesc lang="en">
            When a file is created, the necessary permissions are calculated according to the mapping from DOS modes to UNIX permissions,
            and the resulting UNIX mode is then bit-wise ANDed with this parameter. This parameter may be thought of as a bit-wise MASK for the UNIX modes of a file. 
            </longdesc>
            <shortdesc lang="en">create mask parameter</shortdesc>
            <content type="string" default="${OCF_RESKEY_create_mask_default}" />
        </parameter>
        
        <parameter name="printable" unique="0" required="0">
            <longdesc lang="en">
            If this parameter is yes, then clients may open, write to and submit spool files on the directory specified for the service.
            </longdesc>
            <shortdesc lang="en">printable parameter</shortdesc>
            <content type="string" default="${OCF_RESKEY_printable_default}" />
        </parameter>
        
        <parameter name="valid_users" unique="0" required="0">
            <longdesc lang="en">
            This is a list of users that should be allowed to login to this service. Names starting with @, + and &amp; are interpreted
            using the same rules as described in the invalid users parameter.
            </longdesc>
            <shortdesc lang="en">valid users parameter</shortdesc>
            <content type="string" default="${OCF_RESKEY_valid_users_default}" />
        </parameter>
        
        <parameter name="force_user" unique="0" required="0">
            <longdesc lang="en">
            This specifies a UNIX user name that will be assigned as the default user for all users connecting to this service. This is useful for sharing files.
            </longdesc>
            <shortdesc lang="en">force user parameter</shortdesc>
            <content type="string" default="${OCF_RESKEY_force_user_default}" />
        </parameter>
        
        <parameter name="force_group" unique="0" required="0">
            <longdesc lang="en">
            This specifies a UNIX group name that will be assigned as the default primary group for all users connecting to this service.
            This is useful for sharing files by ensuring that all access to files on service will use the named group for their permissions checking.
            </longdesc>
            <shortdesc lang="en">force group parameter</shortdesc>
            <content type="string" default="${OCF_RESKEY_force_group_default}" />
        </parameter>
        
        <parameter name="extraopt" unique="0" required="0">
            <longdesc lang="en">
            This option can be used to define an additional key = value pair.
            In this parameter also a semicolon could be placed.
            Need to set e.g somthinspecial = value
            </longdesc>
            <shortdesc lang="en">additional key value pair</shortdesc>
            <content type="string" default="${OCF_RESKEY_extraopt_default}" />
        </parameter>
        
        <parameter name="extraopt_list" unique="0" required="0">
            <longdesc lang="en">
            This option can be used to define multiple additional key = value pairs.
            Define the list of element semicolon separated.
            e.g somethingspecial = value;one more = value2
            </longdesc>
            <shortdesc lang="en">additional key value pairs as semicolon separated list</shortdesc>
            <content type="string" default="${OCF_RESKEY_extraopt_list_default}" />
        </parameter>
        
        <parameter name="outfile" unique="1" required="1">
            <longdesc lang="en">
            Set the path and filename where the snipped should be written.
            example "/etc/samba/conf.d/myshare.inc".
            </longdesc>
            <shortdesc lang="en">outputfile</shortdesc>
            <content type="string" default="${OCF_RESKEY_outfile_default}" />
        </parameter>
        
        <parameter name="confd" unique="0" required="0">
            <longdesc lang="en">
            Set the path where the includes will be written. This folder have to be a tmpfs mount
            This defaults to "/etc/samba/conf.d".
            </longdesc>
            <shortdesc lang="en">confd directory</shortdesc>
            <content type="string" default="${OCF_RESKEY_confd_default}" />
        </parameter>
        
        <parameter name="includesfile" unique="0" required="0">
            <longdesc lang="en">
            Set the path and filename in which the include should be placed.
            example includesfile "/etc/samba/conf.d/pacemaker-includes.conf".
            This option manages the include= parameter within this file
            </longdesc>
            <shortdesc lang="en">includesfile for smb.conf</shortdesc>
            <content type="string" default="${OCF_RESKEY_includesfile_default}" />
        </parameter>
        
    </parameters>
    
    <actions>
        <action name="start" timeout="20s" />
        <action name="stop" timeout="20s" />
        <action name="status" depth="0" timeout="20s" interval="10s" />
        <action name="monitor" depth="0" timeout="20s" interval="10s" />
        <action name="meta-data"  timeout="5s" />
        <action name="validate-all" timeout="20s" />
    </actions>
</resource-agent>
END

        exit $OCF_SUCCESS
}

smb_share_addinclude() {
        if [ ! -e ${OCF_RESKEY_includesfile} ];then
            echo '[global]' >  ${OCF_RESKEY_includesfile}
        fi
        if [ $(grep -c "include = $OCF_RESKEY_outfile" ${OCF_RESKEY_includesfile}) -eq 0 ];then
            echo "include = $OCF_RESKEY_outfile" >> ${OCF_RESKEY_includesfile}
        fi
}

smb_share_delinclude() {
        ESCAPED=$(echo $OCF_RESKEY_outfile|sed 's,/,\\/,g')
        sed -i /include.=.$ESCAPED/d  ${OCF_RESKEY_includesfile}
}

smb_share_create() {

        echo "[${OCF_RESKEY_share}]" >  $OCF_RESKEY_outfile
        if [ ! -z "$OCF_RESKEY_path" ];then           echo "        path = $OCF_RESKEY_path" >> $OCF_RESKEY_outfile; fi
        if [ ! -z "$OCF_RESKEY_hosts_allow" ];then    echo "        hosts allow = $OCF_RESKEY_hosts_allow" >> $OCF_RESKEY_outfile; fi
        if [ ! -z "$OCF_RESKEY_browseable" ];then     echo "        browseable = $OCF_RESKEY_browseable" >> $OCF_RESKEY_outfile; fi
        if [ ! -z "$OCF_RESKEY_writeable" ];then      echo "        writeable = $OCF_RESKEY_writeable" >> $OCF_RESKEY_outfile; fi
        if [ ! -z "$OCF_RESKEY_read_only" ];then      echo "        read only = $OCF_RESKEY_read_only" >> $OCF_RESKEY_outfile; fi
        if [ ! -z "$OCF_RESKEY_guest_ok" ];then       echo "        guest ok = $OCF_RESKEY_guest_ok" >> $OCF_RESKEY_outfile; fi
        if [ ! -z "$OCF_RESKEY_directory_mask" ];then echo "        directory mask = $OCF_RESKEY_directory_mask" >> $OCF_RESKEY_outfile; fi
        if [ ! -z "$OCF_RESKEY_create_mask" ];then    echo "        create mask = $OCF_RESKEY_create_mask" >> $OCF_RESKEY_outfile; fi
        if [ ! -z "$OCF_RESKEY_printable" ];then      echo "        printable = $OCF_RESKEY_printable" >> $OCF_RESKEY_outfile; fi
        if [ ! -z "$OCF_RESKEY_valid_users" ];then    echo "        valid users = $OCF_RESKEY_valid_users" >> $OCF_RESKEY_outfile; fi
        if [ ! -z "$OCF_RESKEY_force_user" ];then     echo "        force user = $OCF_RESKEY_force_user" >> $OCF_RESKEY_outfile; fi
        if [ ! -z "$OCF_RESKEY_force_group" ];then    echo "        force group = $OCF_RESKEY_force_group" >> $OCF_RESKEY_outfile; fi
        if [ ! -z "$OCF_RESKEY_extraopt" ];then       echo "        $OCF_RESKEY_extraopt" >> $OCF_RESKEY_outfile; fi
        if [ ! -z "$OCF_RESKEY_extraopt_list" ];then
            IFS=';' read -r -a array <<< "$OCF_RESKEY_extraopt_list"
            for i in "${array[@]}";do
                echo "        $i" >> $OCF_RESKEY_outfile;
            done
        fi
        smb_share_addinclude
}

smb_share_delete() {
        if [ -e $OCF_RESKEY_outfile ];then
            rm -f $OCF_RESKEY_outfile 2>/dev/null
            smb_share_delinclude
            exit $OCF_SUCCESS
        fi
}

smb_share_reloadconfig() {
        smbcontrol smbd reload-config 2>/dev/null
        if [ $? -eq 0 ];then
            exit $OCF_SUCCESS
        else
            ocf_log err "Seems you have an error in your samba configuration"
            exit $OCF_ERR_CONFIGURED
        fi
}

smb_share_checktmpmount() {

        ISMOUNT=$(grep $OCF_RESKEY_confd /proc/mounts|grep -c tmpfs)
        if [ $ISMOUNT -eq 0 ];then
            ocf_log err "The directoy /etc/samba/conf.d need to be a tmpfs mount"
            exit $OCF_ERR_CONFIGURED
        fi
}


######################################################################

smb_share_usage() {
        cat <<END
usage: $0 {start|stop|status|monitor|validate-all|meta-data}

Expects to have a fully populated OCF RA-compliant environment set.
END
        return $OCF_SUCCESS
}

smb_share_start() {
        smb_share_create
        smb_share_reloadconfig
}

smb_share_stop() {
        smbcontrol smbd close-share $OCF_RESKEY_share > /dev/null 2>&1
        smb_share_delete
        smb_share_reloadconfig
}

smb_share_monitor() {
        RES=$(smbcontrol smbd ping > /dev/null 2>&1)
        if [ $? -eq 0 ];then
            if [ $(testparm -s 2>/dev/null| egrep -c \\[$OCF_RESKEY_share\\]) -eq 1 ];then
                return $OCF_SUCCESS
            else
                return $OCF_NOT_RUNNING
            fi
        else
            return $OCF_NOT_RUNNING
        fi
}

smb_share_state() {
        smb_share_checktmpmount
        RES=$(smbcontrol smbd ping > /dev/null 2>&1)
        if [ $? -eq 0 ];then
            if [ $(testparm -s 2>/dev/null| egrep -c \\[$OCF_RESKEY_share\\]) -eq 1 ];then
                ocf_log info "Samba share $OCF_RESKEY_share is active"
                return $OCF_SUCCESS
            else
                ocf_log info "Samba share $OCF_RESKEY_share is not active"
                return $OCF_NOT_RUNNING
            fi
        else
            ocf_log info "Samba share $OCF_RESKEY_share is not active"
            return $OCF_NOT_RUNNING
        fi
}

smb_share_validate() {
        return $OCF_SUCCESS
}


case $__OCF_ACTION in
meta-data)      meta_data
                ;;
usage|help)     smb_share_usage
                ;;
esac


case $__OCF_ACTION in
start)          smb_share_start
                ;;
stop)           smb_share_stop
                ;;
status)         smb_share_state
                ;;
monitor)        smb_share_monitor
                ;;
validate-all)   smb_share_validate
                ;;
*)              smb_share_usage
                exit $OCF_ERR_UNIMPLEMENTED
                ;;
esac
exit $?
# vi:sw=4:ts=8: