Deleted Added
full compact
libtacplus.3 (119893) libtacplus.3 (131504)
1.\" Copyright (c) 1998, 2001, 2002, Juniper Networks, Inc.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.

--- 8 unchanged lines hidden (view full) ---

17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
1.\" Copyright (c) 1998, 2001, 2002, Juniper Networks, Inc.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\" notice, this list of conditions and the following disclaimer.

--- 8 unchanged lines hidden (view full) ---

17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
25.\" $FreeBSD: head/lib/libtacplus/libtacplus.3 119893 2003-09-08 19:57:22Z ru $
25.\" $FreeBSD: head/lib/libtacplus/libtacplus.3 131504 2004-07-02 23:52:20Z ru $
26.\"
27.Dd September 2, 1998
28.Dt LIBTACPLUS 3
29.Os
30.Sh NAME
31.Nm libtacplus
32.Nd TACACS+ client library
33.Sh SYNOPSIS

--- 39 unchanged lines hidden (view full) ---

73.Ft int
74.Fn tac_set_user "struct tac_handle *h" "const char *user"
75.Ft const char *
76.Fn tac_strerror "struct tac_handle *h"
77.Sh DESCRIPTION
78The
79.Nm
80library implements the client side of the TACACS+ network access
26.\"
27.Dd September 2, 1998
28.Dt LIBTACPLUS 3
29.Os
30.Sh NAME
31.Nm libtacplus
32.Nd TACACS+ client library
33.Sh SYNOPSIS

--- 39 unchanged lines hidden (view full) ---

73.Ft int
74.Fn tac_set_user "struct tac_handle *h" "const char *user"
75.Ft const char *
76.Fn tac_strerror "struct tac_handle *h"
77.Sh DESCRIPTION
78The
79.Nm
80library implements the client side of the TACACS+ network access
81control protocol. TACACS+ allows clients to perform authentication,
81control protocol.
82TACACS+ allows clients to perform authentication,
82authorization, and accounting by means of network requests to remote
83authorization, and accounting by means of network requests to remote
83servers. This library currently supports only the authentication
84servers.
85This library currently supports only the authentication
84and authorization portion of the protocol.
85.Sh INITIALIZATION
86To use the library, an application must first call
87.Fn tac_open
88to obtain a
89.Va struct tac_handle * ,
90which provides context for subsequent operations.
91Calls to
92.Fn tac_open
86and authorization portion of the protocol.
87.Sh INITIALIZATION
88To use the library, an application must first call
89.Fn tac_open
90to obtain a
91.Va struct tac_handle * ,
92which provides context for subsequent operations.
93Calls to
94.Fn tac_open
93always succeed unless insufficient virtual memory is available. If
95always succeed unless insufficient virtual memory is available.
96If
94the necessary memory cannot be allocated,
95.Fn tac_open
96returns
97.Dv NULL .
98.Pp
99Before issuing any TACACS+ requests, the library must be made aware
97the necessary memory cannot be allocated,
98.Fn tac_open
99returns
100.Dv NULL .
101.Pp
102Before issuing any TACACS+ requests, the library must be made aware
100of the servers it can contact. The easiest way to configure the
103of the servers it can contact.
104The easiest way to configure the
101library is to call
102.Fn tac_config .
103.Fn tac_config
104causes the library to read a configuration file whose format is
105described in
106.Xr tacplus.conf 5 .
107The pathname of the configuration file is passed as the
108.Va file

--- 10 unchanged lines hidden (view full) ---

119The library can also be configured programmatically by calls to
120.Fn tac_add_server .
121The
122.Va host
123parameter specifies the server host, either as a fully qualified
124domain name or as a dotted-quad IP address in text form.
125The
126.Va port
105library is to call
106.Fn tac_config .
107.Fn tac_config
108causes the library to read a configuration file whose format is
109described in
110.Xr tacplus.conf 5 .
111The pathname of the configuration file is passed as the
112.Va file

--- 10 unchanged lines hidden (view full) ---

123The library can also be configured programmatically by calls to
124.Fn tac_add_server .
125The
126.Va host
127parameter specifies the server host, either as a fully qualified
128domain name or as a dotted-quad IP address in text form.
129The
130.Va port
127parameter specifies the TCP port to contact on the server. If
131parameter specifies the TCP port to contact on the server.
132If
128.Va port
129is given as 0, the library uses port 49, the standard TACACS+ port.
130The shared secret for the server host is passed to the
131.Va secret
133.Va port
134is given as 0, the library uses port 49, the standard TACACS+ port.
135The shared secret for the server host is passed to the
136.Va secret
132parameter. It may be any null-terminated string of bytes.
137parameter.
138It may be any null-terminated string of bytes.
133The timeout for receiving replies from the server is passed to the
134.Va timeout
135parameter, in units of seconds.
136The
137.Va flags
138parameter is a bit mask of flags to specify various characteristics of
139The timeout for receiving replies from the server is passed to the
140.Va timeout
141parameter, in units of seconds.
142The
143.Va flags
144parameter is a bit mask of flags to specify various characteristics of
139the server. It may contain:
145the server.
146It may contain:
140.Pp
141.Bl -tag -width Fl
142.It Dv TAC_SRVR_SINGLE_CONNECT
143Causes the library to attempt to negotiate single connection mode
147.Pp
148.Bl -tag -width Fl
149.It Dv TAC_SRVR_SINGLE_CONNECT
150Causes the library to attempt to negotiate single connection mode
144when communicating with the server. In single connection mode, the
151when communicating with the server.
152In single connection mode, the
145original TCP connection is held open for multiple TACACS+ sessions.
146Older servers do not support this mode, and some of them become
147confused if the client attempts to negotiate it.
148.El
149.Pp
150.Fn tac_add_server
151returns 0 on success, or \-1 if an error occurs.
152.Pp
153.Fn tac_add_server
154may be called multiple times, and it may be used together with
155.Fn tac_config .
156At most 10 servers may be specified.
157When multiple servers are given, they are tried in round-robin
153original TCP connection is held open for multiple TACACS+ sessions.
154Older servers do not support this mode, and some of them become
155confused if the client attempts to negotiate it.
156.El
157.Pp
158.Fn tac_add_server
159returns 0 on success, or \-1 if an error occurs.
160.Pp
161.Fn tac_add_server
162may be called multiple times, and it may be used together with
163.Fn tac_config .
164At most 10 servers may be specified.
165When multiple servers are given, they are tried in round-robin
158fashion until a working, accessible server is found. Once the
166fashion until a working, accessible server is found.
167Once the
159library finds such a server, it continues to use it as long as it
160works.
161.Sh CREATING A TACACS+ AUTHENTICATION REQUEST
162To begin constructing a new authentication request, call
163.Fn tac_create_authen .
164The
165.Va action ,
166.Va type ,
167and
168.Va service
169arguments must be set to appropriate values as defined in the
168library finds such a server, it continues to use it as long as it
169works.
170.Sh CREATING A TACACS+ AUTHENTICATION REQUEST
171To begin constructing a new authentication request, call
172.Fn tac_create_authen .
173The
174.Va action ,
175.Va type ,
176and
177.Va service
178arguments must be set to appropriate values as defined in the
170TACACS+ protocol specification. The
179TACACS+ protocol specification.
180The
171.In taclib.h
172header file contains symbolic constants for these values.
173.Sh CREATING A TACACS+ AUTHORIZATION REQUEST
174To begin constructing a new authorization request, call
175.Fn tac_create_author .
176The
177.Va method ,
178.Va type ,
179and
180.Va service
181arguments must be set to appropriate values as defined in the
181.In taclib.h
182header file contains symbolic constants for these values.
183.Sh CREATING A TACACS+ AUTHORIZATION REQUEST
184To begin constructing a new authorization request, call
185.Fn tac_create_author .
186The
187.Va method ,
188.Va type ,
189and
190.Va service
191arguments must be set to appropriate values as defined in the
182TACACS+ protocol specification. The
192TACACS+ protocol specification.
193The
183.In taclib.h
184header file contains symbolic constants for these values.
185.Sh SETTING OPTIONAL PARAMETERS ON A REQUEST
186After creating a request,
187various optional parameters may be attached to it through calls to
188.Fn tac_set_av ,
189.Fn tac_set_data ,
190.Fn tac_set_port ,
191.Fn tac_set_priv ,
192.Fn tac_set_rem_addr ,
193and
194.Fn tac_set_user .
195The library creates its own copies of any strings provided to these
196functions, so that it is not necessary for the caller to preserve
194.In taclib.h
195header file contains symbolic constants for these values.
196.Sh SETTING OPTIONAL PARAMETERS ON A REQUEST
197After creating a request,
198various optional parameters may be attached to it through calls to
199.Fn tac_set_av ,
200.Fn tac_set_data ,
201.Fn tac_set_port ,
202.Fn tac_set_priv ,
203.Fn tac_set_rem_addr ,
204and
205.Fn tac_set_user .
206The library creates its own copies of any strings provided to these
207functions, so that it is not necessary for the caller to preserve
197them. By default, each of these parameters is empty except for the
208them.
209By default, each of these parameters is empty except for the
198privilege level, which defaults to
199.Ql USER
200privilege.
201.Pp
202.Fn tac_set_av
210privilege level, which defaults to
211.Ql USER
212privilege.
213.Pp
214.Fn tac_set_av
203only applies to the context of an authorization request. The format
215only applies to the context of an authorization request.
216The format
204for an attribute value pair is defined in the TACACS+ protocol
217for an attribute value pair is defined in the TACACS+ protocol
205specification. The index specified can be any value between 0 and
218specification.
219The index specified can be any value between 0 and
206255 inclusive and indicates the position in the list to place the
220255 inclusive and indicates the position in the list to place the
207attribute value pair. Calling
221attribute value pair.
222Calling
208.Fn tac_set_av
209with same index twice effectively replaces the value at that position.
210Use
211.Fn tac_clear_avs
212to clear all attribute value pairs that may have been set.
213.Sh SENDING THE AUTHENTICATION REQUEST AND RECEIVING THE RESPONSE
214After the TACACS+ authentication request has been constructed, it is
215sent by means of
216.Fn tac_send_authen .
217This function connects to a server if not already connected, sends
223.Fn tac_set_av
224with same index twice effectively replaces the value at that position.
225Use
226.Fn tac_clear_avs
227to clear all attribute value pairs that may have been set.
228.Sh SENDING THE AUTHENTICATION REQUEST AND RECEIVING THE RESPONSE
229After the TACACS+ authentication request has been constructed, it is
230sent by means of
231.Fn tac_send_authen .
232This function connects to a server if not already connected, sends
218the request, and waits for a reply. On failure,
233the request, and waits for a reply.
234On failure,
219.Fn tac_send_authen
235.Fn tac_send_authen
220returns \-1. Otherwise, it returns the TACACS+ status code and flags,
221packed into an integer value. The status can be extracted using the
236returns \-1.
237Otherwise, it returns the TACACS+ status code and flags,
238packed into an integer value.
239The status can be extracted using the
222macro
223.Fn TAC_AUTHEN_STATUS .
224Possible status codes, defined in
225.In taclib.h ,
226include:
227.Pp
228.Bl -item -compact -offset indent
229.It

--- 14 unchanged lines hidden (view full) ---

244.Dv TAC_AUTHEN_STATUS_FOLLOW
245.El
246.Pp
247The only flag is the no-echo flag, which can be tested using the
248macro
249.Fn TAC_AUTHEN_NOECHO .
250.Sh EXTRACTING INFORMATION FROM THE SERVER'S AUTHENTICATION RESPONSE
251An authentication response packet from the server may contain a
240macro
241.Fn TAC_AUTHEN_STATUS .
242Possible status codes, defined in
243.In taclib.h ,
244include:
245.Pp
246.Bl -item -compact -offset indent
247.It

--- 14 unchanged lines hidden (view full) ---

262.Dv TAC_AUTHEN_STATUS_FOLLOW
263.El
264.Pp
265The only flag is the no-echo flag, which can be tested using the
266macro
267.Fn TAC_AUTHEN_NOECHO .
268.Sh EXTRACTING INFORMATION FROM THE SERVER'S AUTHENTICATION RESPONSE
269An authentication response packet from the server may contain a
252server message, a data string, or both. After a successful call to
270server message, a data string, or both.
271After a successful call to
253.Fn tac_send_authen ,
254this information may be retrieved from the response by calling
255.Fn tac_get_msg
256and
257.Fn tac_get_data .
258These functions return dynamically-allocated copies of the
272.Fn tac_send_authen ,
273this information may be retrieved from the response by calling
274.Fn tac_get_msg
275and
276.Fn tac_get_data .
277These functions return dynamically-allocated copies of the
259information from the packet. The caller is responsible for freeing
260the copies when it no longer needs them. The data returned from
278information from the packet.
279The caller is responsible for freeing
280the copies when it no longer needs them.
281The data returned from
261these functions is guaranteed to be terminated by a null byte.
262.Pp
263In the case of
264.Fn tac_get_data ,
265the
266.Va len
267argument points to a location into which the library will store the
268actual length of the received data, not including the null
282these functions is guaranteed to be terminated by a null byte.
283.Pp
284In the case of
285.Fn tac_get_data ,
286the
287.Va len
288argument points to a location into which the library will store the
289actual length of the received data, not including the null
269terminator. This argument may be given as
290terminator.
291This argument may be given as
270.Dv NULL
271if the caller is not interested in the length.
272.Sh SENDING AUTHENTICATION CONTINUE PACKETS
273If
274.Fn tac_send_authen
275returns a value containing one of the status codes
276.Dv TAC_AUTHEN_STATUS_GETDATA ,
277.Dv TAC_AUTHEN_STATUS_GETUSER ,
278or
279.Dv TAC_AUTHEN_STATUS_GETPASS ,
280then the client must provide additional information to the server by
292.Dv NULL
293if the caller is not interested in the length.
294.Sh SENDING AUTHENTICATION CONTINUE PACKETS
295If
296.Fn tac_send_authen
297returns a value containing one of the status codes
298.Dv TAC_AUTHEN_STATUS_GETDATA ,
299.Dv TAC_AUTHEN_STATUS_GETUSER ,
300or
301.Dv TAC_AUTHEN_STATUS_GETPASS ,
302then the client must provide additional information to the server by
281means of a TACACS+ CONTINUE packet. To do so, the application must
303means of a TACACS+ CONTINUE packet.
304To do so, the application must
282first set the packet's user message and/or data fields using
283.Fn tac_set_msg
284and
285.Fn tac_set_data .
286The client then sends the CONTINUE packet with
287.Fn tac_send_authen .
288N.B.,
289.Fn tac_create_authen

--- 10 unchanged lines hidden (view full) ---

300.Dv TAC_AUTHEN_STATUS_GETPASS .
301The application should send further CONTINUEs until some other
302status is received from the server.
303.Sh SENDING THE AUTHORIZATION REQUEST AND RECEIVING THE RESPONSE
304After the TACACS+ authorization request has been constructed, it
305is sent by means of
306.Fn tac_send_author .
307This function connects to a server if not already connected, sends
305first set the packet's user message and/or data fields using
306.Fn tac_set_msg
307and
308.Fn tac_set_data .
309The client then sends the CONTINUE packet with
310.Fn tac_send_authen .
311N.B.,
312.Fn tac_create_authen

--- 10 unchanged lines hidden (view full) ---

323.Dv TAC_AUTHEN_STATUS_GETPASS .
324The application should send further CONTINUEs until some other
325status is received from the server.
326.Sh SENDING THE AUTHORIZATION REQUEST AND RECEIVING THE RESPONSE
327After the TACACS+ authorization request has been constructed, it
328is sent by means of
329.Fn tac_send_author .
330This function connects to a server if not already connected, sends
308the request, and waits for a reply. On failure,
331the request, and waits for a reply.
332On failure,
309.Fn tac_send_author
333.Fn tac_send_author
310returns \-1. Otherwise, it returns the TACACS+ status code and
334returns \-1.
335Otherwise, it returns the TACACS+ status code and
311number of attribute value (AV) pairs received packed into an
336number of attribute value (AV) pairs received packed into an
312integer value. The status can be extracted using the macro
337integer value.
338The status can be extracted using the macro
313.Fn TAC_AUTHOR_STATUS .
314Possible status codes, defined in
315.In taclib.h ,
316include:
317.Pp
318.Bl -item -compact -offset indent
319.It
320.Dv TAC_AUTHOR_STATUS_PASS_ADD

--- 5 unchanged lines hidden (view full) ---

326.Dv TAC_AUTHOR_STATUS_ERROR
327.El
328.Pp
329The number of AV pairs received is obtained using
330.Fn TAC_AUTHEN_AV_COUNT .
331.Sh EXTRACTING INFORMATION FROM THE SERVER'S AUTHORIZATION RESPONSE
332Like an authentication response packet, an authorization
333response packet from the
339.Fn TAC_AUTHOR_STATUS .
340Possible status codes, defined in
341.In taclib.h ,
342include:
343.Pp
344.Bl -item -compact -offset indent
345.It
346.Dv TAC_AUTHOR_STATUS_PASS_ADD

--- 5 unchanged lines hidden (view full) ---

352.Dv TAC_AUTHOR_STATUS_ERROR
353.El
354.Pp
355The number of AV pairs received is obtained using
356.Fn TAC_AUTHEN_AV_COUNT .
357.Sh EXTRACTING INFORMATION FROM THE SERVER'S AUTHORIZATION RESPONSE
358Like an authentication response packet, an authorization
359response packet from the
334server may contain a server message, a data string, or both. Refer
360server may contain a server message, a data string, or both.
361Refer
335to EXTRACTING INFORMATION FROM THE SERVER'S AUTHENTICATION RESPONSE
336for instruction on extraction of those values.
337.Pp
338An authorization response packet from the server may also contain
362to EXTRACTING INFORMATION FROM THE SERVER'S AUTHENTICATION RESPONSE
363for instruction on extraction of those values.
364.Pp
365An authorization response packet from the server may also contain
339attribute value (AV) pairs. To extract these, use
366attribute value (AV) pairs.
367To extract these, use
340.Fn tac_get_av
341or
342.Fn tac_get_av_value .
343.Fn tac_get_av
344takes the index of the AV pair as it is positioned in the list.
345The indexes start at 0 (use
346.Fn TAC_AUTHEN_AV_COUNT
347on the return value of
348.Fn tac_send_author
349to get the total number of items in this list).
350Alternatively,
351.Fn tac_get_av_value
352can be used.
353.Fn tac_get_av_value
354takes the attribute name and returns the
368.Fn tac_get_av
369or
370.Fn tac_get_av_value .
371.Fn tac_get_av
372takes the index of the AV pair as it is positioned in the list.
373The indexes start at 0 (use
374.Fn TAC_AUTHEN_AV_COUNT
375on the return value of
376.Fn tac_send_author
377to get the total number of items in this list).
378Alternatively,
379.Fn tac_get_av_value
380can be used.
381.Fn tac_get_av_value
382takes the attribute name and returns the
355corresponding value only, not the AV pair. These functions return
383corresponding value only, not the AV pair.
384These functions return
356dynamically-allocated copies of the information from the packet.
357The caller is responsible for freeing the copies when it no longer
385dynamically-allocated copies of the information from the packet.
386The caller is responsible for freeing the copies when it no longer
358needs them. The data returned from these functions is guaranteed
387needs them.
388The data returned from these functions is guaranteed
359to be terminated by a null byte.
360.Sh OBTAINING ERROR MESSAGES
361Those functions which accept a
362.Va struct tac_handle *
389to be terminated by a null byte.
390.Sh OBTAINING ERROR MESSAGES
391Those functions which accept a
392.Va struct tac_handle *
363argument record an error message if they fail. The error message
393argument record an error message if they fail.
394The error message
364can be retrieved by calling
365.Fn tac_strerror .
366The message text is overwritten on each new error for the given
367.Va struct tac_handle * .
368Thus the message must be copied if it is to be preserved through
369subsequent library calls using the same handle.
370.Sh CLEANUP
371To free the resources used by the TACACS+ library, call
372.Fn tac_close .
373.Sh RETURN VALUES
395can be retrieved by calling
396.Fn tac_strerror .
397The message text is overwritten on each new error for the given
398.Va struct tac_handle * .
399Thus the message must be copied if it is to be preserved through
400subsequent library calls using the same handle.
401.Sh CLEANUP
402To free the resources used by the TACACS+ library, call
403.Fn tac_close .
404.Sh RETURN VALUES
374The following functions return a non-negative value on success. If
405The following functions return a non-negative value on success.
406If
375they detect an error, they return \-1 and record an error message
376which can be retrieved using
377.Fn tac_strerror .
378.Pp
379.Bl -item -offset indent -compact
380.It
381.Fn tac_add_server
382.It

--- 19 unchanged lines hidden (view full) ---

402.It
403.Fn tac_set_rem_addr
404.It
405.Fn tac_set_user
406.El
407.Pp
408The following functions return a
409.No non- Ns Dv NULL
407they detect an error, they return \-1 and record an error message
408which can be retrieved using
409.Fn tac_strerror .
410.Pp
411.Bl -item -offset indent -compact
412.It
413.Fn tac_add_server
414.It

--- 19 unchanged lines hidden (view full) ---

434.It
435.Fn tac_set_rem_addr
436.It
437.Fn tac_set_user
438.El
439.Pp
440The following functions return a
441.No non- Ns Dv NULL
410pointer on success. If they are unable to allocate sufficient
442pointer on success.
443If they are unable to allocate sufficient
411virtual memory, they return
412.Dv NULL
413and record an error message which can be retrieved using
414.Fn tac_strerror .
415.Pp
416.Bl -item -offset indent -compact
417.It
418.Fn tac_get_av
419.It
420.Fn tac_get_av_pair
421.It
422.Fn tac_get_data
423.It
424.Fn tac_get_msg
425.El
426.Pp
427The following functions return a
428.No non- Ns Dv NULL
444virtual memory, they return
445.Dv NULL
446and record an error message which can be retrieved using
447.Fn tac_strerror .
448.Pp
449.Bl -item -offset indent -compact
450.It
451.Fn tac_get_av
452.It
453.Fn tac_get_av_pair
454.It
455.Fn tac_get_data
456.It
457.Fn tac_get_msg
458.El
459.Pp
460The following functions return a
461.No non- Ns Dv NULL
429pointer on success. If they are unable to allocate sufficient
462pointer on success.
463If they are unable to allocate sufficient
430virtual memory, they return
431.Dv NULL ,
432without recording an error message.
433.Pp
434.Bl -item -offset indent -compact
435.It
436.Fn tac_open
437.El

--- 19 unchanged lines hidden ---
464virtual memory, they return
465.Dv NULL ,
466without recording an error message.
467.Pp
468.Bl -item -offset indent -compact
469.It
470.Fn tac_open
471.El

--- 19 unchanged lines hidden ---