*** empty log message ***
[heimdal.git] / lib / auth / sia / sia.c
blob70566ff690c6c3468c43e9e234b445413fc4da94
1 /*
2 * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the Kungliga Tekniska
20 * Högskolan and its contributors.
22 * 4. Neither the name of the Institute nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
39 #ifdef HAVE_CONFIG_H
40 #include <config.h>
41 RCSID("$Id$");
42 #endif
43 #include <stdio.h>
44 #include <string.h>
45 #include <siad.h>
46 #include <pwd.h>
48 #include <krb.h>
49 #include <kafs.h>
52 #ifndef POSIX_GETPWNAM_R
54 /* These functions translate from the old Digital UNIX 3.x interface
55 * to POSIX.1c.
58 static int
59 posix_getpwnam_r(const char *name, struct passwd *pwd,
60 char *buffer, int len, struct passwd **result)
62 int ret = getpwnam_r(name, pwd, buffer, len);
63 if(ret == 0)
64 *result = pwd;
65 else{
66 *result = NULL;
67 ret = _Geterrno();
68 if(ret == 0){
69 ret = ERANGE;
70 _Seterrno(ret);
73 return ret;
76 #define getpwnam_r posix_getpwnam_r
78 static int
79 posix_getpwuid_r(uid_t uid, struct passwd *pwd,
80 char *buffer, int len, struct passwd **result)
82 int ret = getpwuid_r(uid, pwd, buffer, len);
83 if(ret == 0)
84 *result = pwd;
85 else{
86 *result = NULL;
87 ret = _Geterrno();
88 if(ret == 0){
89 ret = ERANGE;
90 _Seterrno(ret);
93 return ret;
96 #define getpwuid_r posix_getpwuid_r
98 #endif /* POSIX_GETPWNAM_R */
100 struct state{
101 char ticket[MaxPathLen];
102 int valid;
105 int
106 siad_init(void)
108 return SIADSUCCESS;
111 int
112 siad_chk_invoker(void)
114 return SIADFAIL;
117 int
118 siad_ses_init(SIAENTITY *entity, int pkgind)
120 struct state *s = malloc(sizeof(*s));
121 if(s == NULL)
122 return SIADFAIL;
123 memset(s, 0, sizeof(*s));
124 entity->mech[pkgind] = (int*)s;
125 return SIADSUCCESS;
128 static int
129 setup_name(SIAENTITY *e, prompt_t *p)
131 e->name = malloc(SIANAMEMIN+1);
132 if(e->name == NULL)
133 return SIADFAIL;
134 p->prompt = (unsigned char*)"login: ";
135 p->result = (unsigned char*)e->name;
136 p->min_result_length = 1;
137 p->max_result_length = SIANAMEMIN;
138 p->control_flags = 0;
139 return SIADSUCCESS;
142 static int
143 setup_password(SIAENTITY *e, prompt_t *p)
145 e->password = malloc(SIAMXPASSWORD+1);
146 if(e->password == NULL)
147 return SIADFAIL;
148 p->prompt = (unsigned char*)"Password: ";
149 p->result = (unsigned char*)e->password;
150 p->min_result_length = 0;
151 p->max_result_length = SIAMXPASSWORD;
152 p->control_flags = SIARESINVIS;
153 return SIADSUCCESS;
157 static int
158 common_auth(sia_collect_func_t *collect,
159 SIAENTITY *entity,
160 int siastat,
161 int pkgind)
163 prompt_t prompts[2], *pr;
164 char *toname, *toinst;
166 if((siastat == SIADSUCCESS) && (geteuid() == 0))
167 return SIADSUCCESS;
168 if(entity == NULL)
169 return SIADFAIL | SIADSTOP;
170 if((entity->acctname != NULL) || (entity->pwd != NULL))
171 return SIADFAIL | SIADSTOP;
173 if((collect != NULL) && entity->colinput) {
174 int num;
175 pr = prompts;
176 if(entity->name == NULL){
177 if(setup_name(entity, pr) != SIADSUCCESS)
178 return SIADFAIL;
179 pr++;
181 if(entity->password == NULL){
182 if(setup_password(entity, pr) != SIADSUCCESS)
183 return SIADFAIL;
184 pr++;
186 num = pr - prompts;
187 if(num == 1){
188 if((*collect)(240, SIAONELINER, (unsigned char*)"", num,
189 prompts) != SIACOLSUCCESS)
190 return SIADFAIL | SIADSTOP;
191 } else if(num > 0){
192 if((*collect)(0, SIAFORM, (unsigned char*)"", num,
193 prompts) != SIACOLSUCCESS)
194 return SIADFAIL | SIADSTOP;
198 if(entity->password == NULL || strlen(entity->password) > SIAMXPASSWORD)
199 return SIADFAIL;
200 if(entity->name[0] == 0)
201 return SIADFAIL;
204 char realm[REALM_SZ];
205 int ret;
206 struct passwd pw, *pwd, fpw, *fpwd;
207 char pwbuf[1024], fpwbuf[1024];
208 struct state *s = (struct state*)entity->mech[pkgind];
210 if(getpwnam_r(entity->name, &pw, pwbuf, sizeof(pwbuf), &pwd) != 0)
211 return SIADFAIL;
213 snprintf(s->ticket, sizeof(s->ticket),
214 TKT_ROOT "%u_%u", (unsigned)pwd->pw_uid, (unsigned)getpid());
215 krb_get_lrealm(realm, 1);
216 toname = entity->name;
217 toinst = "";
218 if(entity->authtype == SIA_A_SUAUTH){
219 uid_t ouid;
220 #ifdef SIAENTITY_HAS_OUID
221 ouid = entity->ouid;
222 #else
223 ouid = getuid();
224 #endif
225 if(getpwuid_r(ouid, &fpw, fpwbuf, sizeof(fpwbuf), &fpwd) != 0)
226 return SIADFAIL;
227 snprintf(s->ticket, sizeof(s->ticket), TKT_ROOT "_%s_to_%s_%d",
228 fpwd->pw_name, pwd->pw_name, getpid());
229 if(strcmp(pwd->pw_name, "root") == 0){
230 toname = fpwd->pw_name;
231 toinst = pwd->pw_name;
235 krb_set_tkt_string(s->ticket);
237 setuid(0); /* XXX fix for fix in tf_util.c */
238 if(krb_kuserok(toname, toinst, realm, entity->name))
239 return SIADFAIL;
240 ret = krb_verify_user(toname, toinst, realm,
241 entity->password, 1, NULL, "");
242 if(ret){
243 if(ret != KDC_PR_UNKNOWN)
244 /* since this is most likely a local user (such as
245 root), just silently return failure when the
246 principal doesn't exist */
247 SIALOG("WARNING", "krb_verify_user(%s.%s): %s",
248 toname, toinst, krb_get_err_text(ret));
249 return SIADFAIL;
251 if(sia_make_entity_pwd(pwd, entity) == SIAFAIL)
252 return SIADFAIL;
253 s->valid = 1;
255 return SIADSUCCESS;
259 int
260 siad_ses_authent(sia_collect_func_t *collect,
261 SIAENTITY *entity,
262 int siastat,
263 int pkgind)
265 return common_auth(collect, entity, siastat, pkgind);
268 int
269 siad_ses_estab(sia_collect_func_t *collect,
270 SIAENTITY *entity, int pkgind)
272 return SIADFAIL;
275 int
276 siad_ses_launch(sia_collect_func_t *collect,
277 SIAENTITY *entity,
278 int pkgind)
280 char buf[MaxPathLen];
281 static char env[MaxPathLen];
282 struct state *s = (struct state*)entity->mech[pkgind];
283 if(s->valid){
284 chown(s->ticket, entity->pwd->pw_uid, entity->pwd->pw_gid);
285 snprintf(env, sizeof(env), "KRBTKFILE=%s", s->ticket);
286 putenv(env);
288 if (k_hasafs()) {
289 char cell[64];
290 k_setpag();
291 if(k_afs_cell_of_file(entity->pwd->pw_dir, cell, sizeof(cell)) == 0)
292 krb_afslog(cell, 0);
293 krb_afslog(0, 0);
295 return SIADSUCCESS;
298 int
299 siad_ses_release(SIAENTITY *entity, int pkgind)
301 if(entity->mech[pkgind])
302 free(entity->mech[pkgind]);
303 return SIADSUCCESS;
306 int
307 siad_ses_suauthent(sia_collect_func_t *collect,
308 SIAENTITY *entity,
309 int siastat,
310 int pkgind)
312 if(geteuid() != 0)
313 return SIADFAIL;
314 if(entity->name == NULL)
315 return SIADFAIL;
316 if(entity->name[0] == 0)
317 strcpy(entity->name, "root");
318 return common_auth(collect, entity, siastat, pkgind);
321 /* The following functions returns the default fail */
324 siad_ses_reauthent (sia_collect_func_t *collect,
325 SIAENTITY *entity,
326 int siastat,
327 int pkgind)
329 return SIADFAIL;
333 siad_chg_finger (sia_collect_func_t *collect,
334 const char *username,
335 int argc,
336 char *argv[])
338 return SIADFAIL;
342 siad_chg_passwd (sia_collect_func_t *collect,
343 const char *username,
344 int argc,
345 char *argv[])
347 return SIADFAIL;
351 siad_chg_shell (sia_collect_func_t *collect,
352 const char *username,
353 int argc,
354 char *argv[])
356 return SIADFAIL;
360 siad_getpwent(struct passwd *result,
361 char *buf,
362 int bufsize,
363 struct sia_context *context)
365 return SIADFAIL;
369 siad_getpwuid (uid_t uid,
370 struct passwd *result,
371 char *buf,
372 int bufsize,
373 struct sia_context *context)
375 return SIADFAIL;
379 siad_getpwnam (const char *name,
380 struct passwd *result,
381 char *buf,
382 int bufsize,
383 struct sia_context *context)
385 return SIADFAIL;
389 siad_setpwent (struct sia_context *context)
391 return SIADFAIL;
395 siad_endpwent (struct sia_context *context)
397 return SIADFAIL;
401 siad_getgrent(struct group *result,
402 char *buf,
403 int bufsize,
404 struct sia_context *context)
406 return SIADFAIL;
410 siad_getgrgid (gid_t gid,
411 struct group *result,
412 char *buf,
413 int bufsize,
414 struct sia_context *context)
416 return SIADFAIL;
420 siad_getgrnam (const char *name,
421 struct group *result,
422 char *buf,
423 int bufsize,
424 struct sia_context *context)
426 return SIADFAIL;
430 siad_setgrent (struct sia_context *context)
432 return SIADFAIL;
436 siad_endgrent (struct sia_context *context)
438 return SIADFAIL;
442 siad_chk_user (const char *logname, int checkflag)
444 return SIADFAIL;