2 * Copyright (c) 1995, 1996, 1997 Kungliga Tekniska Högskolan
3 * (Royal Institute of Technology, Stockholm, Sweden).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
52 #ifndef POSIX_GETPWNAM_R
54 /* These functions translate from the old Digital UNIX 3.x interface
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
);
76 #define getpwnam_r posix_getpwnam_r
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
);
96 #define getpwuid_r posix_getpwuid_r
98 #endif /* POSIX_GETPWNAM_R */
101 char ticket
[MaxPathLen
];
112 siad_chk_invoker(void)
118 siad_ses_init(SIAENTITY
*entity
, int pkgind
)
120 struct state
*s
= malloc(sizeof(*s
));
123 memset(s
, 0, sizeof(*s
));
124 entity
->mech
[pkgind
] = (int*)s
;
129 setup_name(SIAENTITY
*e
, prompt_t
*p
)
131 e
->name
= malloc(SIANAMEMIN
+1);
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;
143 setup_password(SIAENTITY
*e
, prompt_t
*p
)
145 e
->password
= malloc(SIAMXPASSWORD
+1);
146 if(e
->password
== NULL
)
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
;
158 common_auth(sia_collect_func_t
*collect
,
163 prompt_t prompts
[2], *pr
;
164 char *toname
, *toinst
;
166 if((siastat
== SIADSUCCESS
) && (geteuid() == 0))
169 return SIADFAIL
| SIADSTOP
;
170 if((entity
->acctname
!= NULL
) || (entity
->pwd
!= NULL
))
171 return SIADFAIL
| SIADSTOP
;
173 if((collect
!= NULL
) && entity
->colinput
) {
176 if(entity
->name
== NULL
){
177 if(setup_name(entity
, pr
) != SIADSUCCESS
)
181 if(entity
->password
== NULL
){
182 if(setup_password(entity
, pr
) != SIADSUCCESS
)
188 if((*collect
)(240, SIAONELINER
, (unsigned char*)"", num
,
189 prompts
) != SIACOLSUCCESS
)
190 return SIADFAIL
| SIADSTOP
;
192 if((*collect
)(0, SIAFORM
, (unsigned char*)"", num
,
193 prompts
) != SIACOLSUCCESS
)
194 return SIADFAIL
| SIADSTOP
;
198 if(entity
->password
== NULL
|| strlen(entity
->password
) > SIAMXPASSWORD
)
200 if(entity
->name
[0] == 0)
204 char realm
[REALM_SZ
];
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)
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
;
218 if(entity
->authtype
== SIA_A_SUAUTH
){
220 #ifdef SIAENTITY_HAS_OUID
225 if(getpwuid_r(ouid
, &fpw
, fpwbuf
, sizeof(fpwbuf
), &fpwd
) != 0)
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
))
240 ret
= krb_verify_user(toname
, toinst
, realm
,
241 entity
->password
, 1, NULL
, "");
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
));
251 if(sia_make_entity_pwd(pwd
, entity
) == SIAFAIL
)
260 siad_ses_authent(sia_collect_func_t
*collect
,
265 return common_auth(collect
, entity
, siastat
, pkgind
);
269 siad_ses_estab(sia_collect_func_t
*collect
,
270 SIAENTITY
*entity
, int pkgind
)
276 siad_ses_launch(sia_collect_func_t
*collect
,
280 char buf
[MaxPathLen
];
281 static char env
[MaxPathLen
];
282 struct state
*s
= (struct state
*)entity
->mech
[pkgind
];
284 chown(s
->ticket
, entity
->pwd
->pw_uid
, entity
->pwd
->pw_gid
);
285 snprintf(env
, sizeof(env
), "KRBTKFILE=%s", s
->ticket
);
291 if(k_afs_cell_of_file(entity
->pwd
->pw_dir
, cell
, sizeof(cell
)) == 0)
299 siad_ses_release(SIAENTITY
*entity
, int pkgind
)
301 if(entity
->mech
[pkgind
])
302 free(entity
->mech
[pkgind
]);
307 siad_ses_suauthent(sia_collect_func_t
*collect
,
314 if(entity
->name
== NULL
)
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
,
333 siad_chg_finger (sia_collect_func_t
*collect
,
334 const char *username
,
342 siad_chg_passwd (sia_collect_func_t
*collect
,
343 const char *username
,
351 siad_chg_shell (sia_collect_func_t
*collect
,
352 const char *username
,
360 siad_getpwent(struct passwd
*result
,
363 struct sia_context
*context
)
369 siad_getpwuid (uid_t uid
,
370 struct passwd
*result
,
373 struct sia_context
*context
)
379 siad_getpwnam (const char *name
,
380 struct passwd
*result
,
383 struct sia_context
*context
)
389 siad_setpwent (struct sia_context
*context
)
395 siad_endpwent (struct sia_context
*context
)
401 siad_getgrent(struct group
*result
,
404 struct sia_context
*context
)
410 siad_getgrgid (gid_t gid
,
411 struct group
*result
,
414 struct sia_context
*context
)
420 siad_getgrnam (const char *name
,
421 struct group
*result
,
424 struct sia_context
*context
)
430 siad_setgrent (struct sia_context
*context
)
436 siad_endgrent (struct sia_context
*context
)
442 siad_chk_user (const char *logname
, int checkflag
)