Line data Source code
1 : /*
2 : Authors:
3 : Sumit Bose <sbose@redhat.com>
4 :
5 : Copyright (C) 2014 Red Hat
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include <nss.h>
22 : #include <sys/types.h>
23 : #include <pwd.h>
24 : #include <string.h>
25 : #include <strings.h>
26 : #include <errno.h>
27 :
28 : #include <krb5/localauth_plugin.h>
29 :
30 : enum nss_status _nss_sss_getpwnam_r(const char *name, struct passwd *result,
31 : char *buffer, size_t buflen, int *errnop);
32 :
33 : #define DEFAULT_BUFSIZE 4096
34 :
35 0 : static krb5_error_code sss_userok(krb5_context context,
36 : krb5_localauth_moddata data,
37 : krb5_const_principal aname,
38 : const char *lname)
39 : {
40 : krb5_error_code kerr;
41 : char *princ_str;
42 0 : struct passwd pwd = { 0 };
43 0 : char *buffer = NULL;
44 : size_t buflen;
45 : enum nss_status nss_status;
46 : int nss_errno;
47 : uid_t princ_uid;
48 : int ret;
49 :
50 0 : kerr = krb5_unparse_name(context, aname, &princ_str);
51 0 : if (kerr != 0) {
52 0 : return kerr;
53 : }
54 :
55 0 : if (strcasecmp(princ_str, lname) == 0) {
56 0 : ret = 0;
57 0 : goto done;
58 : }
59 :
60 0 : buflen = DEFAULT_BUFSIZE;
61 0 : buffer = malloc(buflen);
62 0 : if (buffer == NULL) {
63 0 : ret = ENOMEM;
64 0 : goto done;
65 : }
66 :
67 0 : nss_status = _nss_sss_getpwnam_r(princ_str, &pwd, buffer, buflen,
68 : &nss_errno);
69 0 : if (nss_status != NSS_STATUS_SUCCESS) {
70 0 : if (nss_status == NSS_STATUS_NOTFOUND) {
71 0 : ret = KRB5_PLUGIN_NO_HANDLE;
72 : } else {
73 0 : ret = EIO;
74 : }
75 0 : goto done;
76 : }
77 :
78 0 : princ_uid = pwd.pw_uid;
79 :
80 0 : nss_status = _nss_sss_getpwnam_r(lname, &pwd, buffer, buflen, &nss_errno);
81 0 : if (nss_status != NSS_STATUS_SUCCESS) {
82 0 : if (nss_status == NSS_STATUS_NOTFOUND) {
83 0 : ret = KRB5_PLUGIN_NO_HANDLE;
84 : } else {
85 0 : ret = EIO;
86 : }
87 0 : goto done;
88 : }
89 :
90 0 : if (princ_uid != pwd.pw_uid) {
91 0 : ret = EPERM;
92 0 : goto done;
93 : }
94 :
95 0 : ret = 0;
96 :
97 : done:
98 0 : krb5_free_unparsed_name(context, princ_str);
99 0 : free(buffer);
100 :
101 0 : return ret;
102 : }
103 :
104 0 : static krb5_error_code sss_an2ln(krb5_context context,
105 : krb5_localauth_moddata data,
106 : const char *type, const char *residual,
107 : krb5_const_principal aname, char **lname_out)
108 : {
109 : krb5_error_code kerr;
110 : char *princ_str;
111 0 : struct passwd pwd = { 0 };
112 0 : char *buffer = NULL;
113 : size_t buflen;
114 : enum nss_status nss_status;
115 : int nss_errno;
116 : int ret;
117 : char *str;
118 :
119 0 : kerr = krb5_unparse_name(context, aname, &princ_str);
120 0 : if (kerr != 0) {
121 0 : return kerr;
122 : }
123 :
124 0 : buflen = DEFAULT_BUFSIZE;
125 0 : buffer = malloc(buflen);
126 0 : if (buffer == NULL) {
127 0 : ret = ENOMEM;
128 0 : goto done;
129 : }
130 :
131 0 : nss_status = _nss_sss_getpwnam_r(princ_str, &pwd, buffer, buflen,
132 : &nss_errno);
133 0 : if (nss_status != NSS_STATUS_SUCCESS) {
134 0 : if (nss_status == NSS_STATUS_NOTFOUND) {
135 0 : ret = KRB5_PLUGIN_NO_HANDLE;
136 : } else {
137 0 : ret = EIO;
138 : }
139 0 : goto done;
140 : }
141 :
142 0 : if (pwd.pw_name == NULL) {
143 0 : ret = EINVAL;
144 0 : goto done;
145 : }
146 :
147 0 : str = strdup(pwd.pw_name);
148 0 : if (str == NULL) {
149 0 : ret = ENOMEM;
150 0 : goto done;
151 : }
152 :
153 0 : *lname_out = str;
154 :
155 0 : ret = 0;
156 :
157 : done:
158 0 : krb5_free_unparsed_name(context, princ_str);
159 0 : free(buffer);
160 :
161 0 : return ret;
162 : }
163 :
164 0 : static void sss_freestr(krb5_context context,
165 : krb5_localauth_moddata data, char *str)
166 : {
167 0 : free(str);
168 0 : }
169 :
170 : krb5_error_code
171 0 : localauth_sssd_initvt(krb5_context context, int maj_ver, int min_ver,
172 : krb5_plugin_vtable vtable)
173 : {
174 :
175 0 : if (maj_ver != 1 || min_ver != 1) {
176 0 : return KRB5_PLUGIN_VER_NOTSUPP;
177 : }
178 :
179 0 : krb5_localauth_vtable vt = (krb5_localauth_vtable)vtable;
180 :
181 0 : vt->init = NULL;
182 0 : vt->fini = NULL;
183 0 : vt->name = "sssd";
184 0 : vt->an2ln = sss_an2ln;
185 0 : vt->userok = sss_userok;
186 0 : vt->free_string = sss_freestr;
187 :
188 0 : return 0;
189 : }
190 :
|