1/*
2 * cap.c - POSIX.1e (POSIX.6) capability set manipulation
3 *
4 * This file is part of zsh, the Z shell.
5 *
6 * Copyright (c) 1997 Andrew Main
7 * All rights reserved.
8 *
9 * Permission is hereby granted, without written agreement and without
10 * license or royalty fees, to use, copy, modify, and distribute this
11 * software and to distribute modified versions of this software for any
12 * purpose, provided that the above copyright notice and the following
13 * two paragraphs appear in all copies of this software.
14 *
15 * In no event shall Andrew Main or the Zsh Development Group be liable
16 * to any party for direct, indirect, special, incidental, or consequential
17 * damages arising out of the use of this software and its documentation,
18 * even if Andrew Main and the Zsh Development Group have been advised of
19 * the possibility of such damage.
20 *
21 * Andrew Main and the Zsh Development Group specifically disclaim any
22 * warranties, including, but not limited to, the implied warranties of
23 * merchantability and fitness for a particular purpose.  The software
24 * provided hereunder is on an "as is" basis, and Andrew Main and the
25 * Zsh Development Group have no obligation to provide maintenance,
26 * support, updates, enhancements, or modifications.
27 *
28 */
29
30#include "cap.mdh"
31#include "cap.pro"
32
33#ifdef HAVE_CAP_GET_PROC
34
35static int
36bin_cap(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
37{
38    int ret = 0;
39    cap_t caps;
40    if(*argv) {
41	unmetafy(*argv, NULL);
42	caps = cap_from_text(*argv);
43	if(!caps) {
44	    zwarnnam(nam, "invalid capability string");
45	    return 1;
46	}
47	if(cap_set_proc(caps)) {
48	    zwarnnam(nam, "can't change capabilities: %e", errno);
49	    ret = 1;
50	}
51    } else {
52	char *result = NULL;
53	ssize_t length;
54	caps = cap_get_proc();
55	if(caps)
56	    result = cap_to_text(caps, &length);
57	if(!caps || !result) {
58	    zwarnnam(nam, "can't get capabilities: %e", errno);
59	    ret = 1;
60	} else
61	    puts(result);
62    }
63    cap_free(caps);
64    return ret;
65}
66
67static int
68bin_getcap(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
69{
70    int ret = 0;
71
72    do {
73	char *result = NULL;
74	ssize_t length;
75	cap_t caps;
76
77	caps = cap_get_file(unmetafy(dupstring(*argv), NULL));
78	if(caps)
79	    result = cap_to_text(caps, &length);
80	if (!caps || !result) {
81	    zwarnnam(nam, "%s: %e", *argv, errno);
82	    ret = 1;
83	} else
84	    printf("%s %s\n", *argv, result);
85	cap_free(caps);
86    } while(*++argv);
87    return ret;
88}
89
90static int
91bin_setcap(char *nam, char **argv, UNUSED(Options ops), UNUSED(int func))
92{
93    cap_t caps;
94    int ret = 0;
95
96    unmetafy(*argv, NULL);
97    caps = cap_from_text(*argv++);
98    if(!caps) {
99	zwarnnam(nam, "invalid capability string");
100	return 1;
101    }
102
103    do {
104	if(cap_set_file(unmetafy(dupstring(*argv), NULL), caps)) {
105	    zwarnnam(nam, "%s: %e", *argv, errno);
106	    ret = 1;
107	}
108    } while(*++argv);
109    cap_free(caps);
110    return ret;
111}
112
113#else /* !HAVE_CAP_GET_PROC */
114
115# define bin_cap    bin_notavail
116# define bin_getcap bin_notavail
117# define bin_setcap bin_notavail
118
119#endif /* !HAVE_CAP_GET_PROC */
120
121/* module paraphernalia */
122
123static struct builtin bintab[] = {
124    BUILTIN("cap",    0, bin_cap,    0,  1, 0, NULL, NULL),
125    BUILTIN("getcap", 0, bin_getcap, 1, -1, 0, NULL, NULL),
126    BUILTIN("setcap", 0, bin_setcap, 2, -1, 0, NULL, NULL),
127};
128
129static struct features module_features = {
130    bintab, sizeof(bintab)/sizeof(*bintab),
131    NULL, 0,
132    NULL, 0,
133    NULL, 0,
134    0
135};
136
137/**/
138int
139setup_(UNUSED(Module m))
140{
141    return 0;
142}
143
144/**/
145int
146features_(Module m, char ***features)
147{
148    *features = featuresarray(m, &module_features);
149    return 0;
150}
151
152/**/
153int
154enables_(Module m, int **enables)
155{
156    return handlefeatures(m, &module_features, enables);
157}
158
159/**/
160int
161boot_(UNUSED(Module m))
162{
163    return 0;
164}
165
166/**/
167int
168cleanup_(Module m)
169{
170    return setfeatureenables(m, &module_features, NULL);
171}
172
173/**/
174int
175finish_(UNUSED(Module m))
176{
177    return 0;
178}
179