由 xiorqe 在 07-03-2003 10:53 发表:
pam是什么东东,怎么解释
同上
由 vion800 在 07-03-2003 13:54 发表:
Pluggable Authentication Modules
由 vion800 在 07-03-2003 13:56 发表:
http://sinbad.zhoubin.com/read.html...NIX#=482
由 tram 在 07-03-2003 14:05 发表:
发信人: Sinbad
1<anonymous@anonymous.com>
2
3标 题: PAM入门介绍
4
5发信站: 辛巴达 (Fri Sep 27 11:01:24 2002)
6
7
8
9作者:netguy (netguy@nsfocus.com)
10
11主页: http://www.nsfocus.com
12
13日期:2000-10-07
14
15
16
17PAM(Pluggable Authentication Modules )是由Sun提出的一种认证机制。它通过提供一些
18
19动态链接库和一套统一的API,将系统提供的服务 和该服务的认证方式分开,使得系统管理
20
21员可以灵活地根据需要给不同的服务配置不同的认证方式而无需更改服务程序,同时也便于
22
23向系 统中添加新的认证手段。
24
25PAM最初是集成在Solaris中,目前已移植到其它系统中,如Linux、SunOS、HP-UX 9.0等。
26
27
28
29一、PAM的结构
30
31
32
33PAM的整个框架结构如下图所示:
34
35
36
37
38
39系统管理员通过PAM配置文件来制定认证策略,即指定什么服务该采用什么样的认证方法;应
40
41用程序开发者通过在服务程序中使用PAM API而实现对认证方法的调用;而PAM服务模块(se
42
43rvice module)的开发者则利用PAM SPI(Service Module API)来编写认证模块(主 要是
44
45引出一些函数pam_sm_xxxx( )供libpam调用),将不同的认证机制(比如传统的UNIX认证方
46
47法、Kerberos等)加入到系统中;PAM核 心库(libpam)则读取配置文件,以此为根据将服
48
49务程序和相应的认证方法联系起来。
50
51二、PAM支持的四种管理界面:
52
53
54
551、认证管理(authentication management)
56
57主要是接受用户名和密码,进而对该用户的密码进行认证,并负责设置用户的一些秘密
58
59信息。
60
612、帐户管理(account management)
62
63主要是检查帐户是否被允许登录系统,帐号是否已经过期,帐号的登录是否有时间段的
64
65限制等等。
66
673、密码管理(password management)
68
69主要是用来修改用户的密码。
70
714、会话管理(session management)
72
73主要是提供对会话的管理和记账(accounting)。
74
75
76
77三、PAM的文件:
78
79
80
81/usr/lib/libpam.so.* PAM核心库
82
83/etc/pam.conf或者/etc/pam.d/ PAM配置文件
84
85/usr/lib/security/pam_*.so 可动态加载的PAM service module
86
87对于RedHat,其目录不是/usr/lib,而是/lib。
88
89
90
91四、PAM的配置:
92
93
94
95PAM的配置是通过单个配置文件/etc/pam.conf。RedHat还支持另外一种配置方式,即通过配
96
97置目录/etc/pam.d/,且这种的优先级要高于单 个配置文件的方式。
98
99
100
1011、使用配置文件/etc/pam.conf
102
103
104
105该文件是由如下的行所组成的:
106
107service-name module-type control-flag module-path arguments
108
109
110
111service-name 服务的名字,比如telnet、login、ftp等,服务名字“OTHER”代表所有没有
112
113在该文件中明确配置的其它服务。
114
115module-type 模块类型有四种:auth、account、session、password,即对应PAM所支持的
116
117四种管理方式。同一个服务可以调用多个 PAM模块进行认证,这些模块构成一个stack。
118
119control-flag 用来告诉PAM库该如何处理与该服务相关的PAM模块的成功或失败情况。它有四
120
121种可能的 值:required,requisite,sufficient,optional。
122
123required 表示本模块必须返回成功才能通过认证,但是如果该模块返回失败的话,失败
124
125结果也不会立即通知用户,而是要等到同一stack 中的所有模块全部执行完毕再将失败结果
126
127返回给应用程序。可以认为是一个必要条件。
128
129requisite 与required类似,该模块必须返回成功才能通过认证,但是一旦该模块返回
130
131失败,将不再执行同一stack内的任何模块,而是直 接将控制权返回给应用程序。是一个必
132
133要条件。注:这种只有RedHat支持,Solaris不支持。
134
135sufficient 表明本模块返回成功已经足以通过身份认证的要求,不必再执行同一stack
136
137内的其它模块,但是如果本模块返回失败的话可以 忽略。可以认为是一个充分条件。
138
139optional表明本模块是可选的,它的成功与否一般不会对身份认证起关键作用,其返回
140
141值一般被忽略。
142
143对于control-flag,从Linux-PAM-0.63版本起,支持一种新的语法,具体可参看Linux
144
145PAM文档。
146
147module-path 用来指明本模块对应的程序文件的路径名,一般采用绝对路径,如果没有给出
148
149绝对路径,默认该文件在目录/usr/lib/security下 面。
150
151arguments 是用来传递给该模块的参数。一般来说每个模块的参数都不相同,可以由该模块
152
153的开发者自己定义,但是也有以下几个共同 的参数:
154
155debug 该模块应当用syslog( )将调试信息写入到系统日志文件中。
156
157no_warn 表明该模块不应把警告信息发送给应用程序。
158
159use_first_pass 表明该模块不能提示用户输入密码,而应使用前一个模块从用户那里
160
161得到的密码。
162
163try_first_pass 表明该模块首先应当使用前一个模块从用户那里得到的密码,如果该
164
165密码验证不通过,再提示用户输入新的密码。
166
167use_mapped_pass 该模块不能提示用户输入密码,而是使用映射过的密码。
168
169expose_account 允许该模块显示用户的帐号名等信息,一般只能在安全的环境下使用
170
171,因为泄漏用户名会对安全造成一定程度的威 胁。
172
173
174
1752、使用配置目录/etc/pam.d/(只适用于RedHat Linux)
176
177
178
179该目录下的每个文件的名字对应服务名,例如ftp服务对应文件/etc/pam.d/ftp。如果名为x
180
181xxx的服务所对应的配置文件/etc/pam.d/xxxx不存 在,则该服务将使用默认的配置文件/et
182
183c/pam.d/other。每个文件由如下格式的文本行所构成:
184
185module-type control-flag module-path arguments
186
187每个字段的含义和/etc/pam.conf中的相同。
188
189
190
1913、配置的例子
192
193
194
195例一:用/etc/pam.conf配置默认的认证方式。
196
197
198
199下面的例子将拒绝所有没有在/etc/pam.conf中明确配置的服务。OTHER代表没有明确配置的
200
201其它所有服务,pam_deny模块的作用只是简 单地拒绝通过认证。
202
203OTHER auth required /usr/lib/security/pam_deny.so
204
205OTHER account required /usr/lib/security/pam_deny.so
206
207OTHER password required /usr/lib/security/pam_deny.so
208
209OTHER session required /usr/lib/security/pam_deny.so
210
211
212
213
214
215例二:通过/etc/pam.d/rsh文件配置rsh服务的认证方式。
216
217
218
219rsh服务认证用户时,先使用/etc/hosts.equiv和.rhosts文件的认证方式,然后再根据/etc
220
221/nologin文件的存在与否来判断是否允许该用户使用 rsh,最后使用password database来认
222
223证用户。
224
225
226
227auth required /lib/security/pam_rhosts_auth.so
228
229auth required /lib/security/pam_nologin.so
230
231account required /lib/security/pam_pwdb.so
232
233session required /lib/security/pam_pwdb.so
234
235
236
237
238
239例三:通过/etc/pam.conf配置ftpd的认证方式。
240
241
242
243下面是ftpd服务利用PAM模块进行用户认证的三个步骤。首先用pam_ftp模块检查当前用户是
244
245否为匿名用户,如果是匿名用户,则 sufficient控制标志表明无需再进行后面的认证步骤,
246
247直接通过认证;否则继续使用pam_unix_auth模块来进行标准的unix认证,即用/etc/ passw
248
249d和/etc/shadow进行认证;通过了pam_unix_auth模块的认证之后,还要继续用pam_listfil
250
251e模块来检查该用户是否出现在文件/etc/ ftpusers中,如果是则该用户被deny掉。
252
253ftpd auth sufficient /usr/lib/security/pam_ftp.so
254
255ftpd auth required /usr/lib/security/pam_unix_auth.so use_first_pass
256
257ftpd auth required /usr/lib/security/pam_listfile.so \
258
259onerr=succeed item=user sense=deny file=/etc/ftpuser
260
261s
262
263
264
265五、密码映射(password-mapping)
266
267
268
269密码映射允许用户在不同的认证机制下使用不同的密码,其中有一个主密码(primary pass
270
271word),其它密码为次密码(secondary passwords,可能有多个)。主密码用来对次密码进
272
273行加密。在主密码认证通过后,认证模块利用主密码将加密过的次密码(也称为 mapped pa
274
275ssword)解密,并对次密码进行认证。
276
277注:如果使用了一次性密码的机制,就不使用密码映射。
278
279
280
281所有服务模块必须支持如下4个映射选项(在第四部分已经简单解释过):
282
283
284
2851、use_first_pass
286
287
288
289这个选项指示本模块不能提示用户输入密码,而是使用已有的密码,即从第一个向用户提示
290
291输入密码的模块那里取得密码,并对该密码进 行认证。
292
293
294
2952、try_first_pass
296
297
298
299这个选项指示本模块首先尝试使用已有的密码,即从第一个向用户提示输入密码的模块那里
300
301取得密码,并对该密码进行认证。如果密码认 证失败,则再提示用户输入密码。
302
303
304
3053、use_mapped_pass
306
307
308
309这个选项指示本模块不能向用户提示输入密码,而应使用映射过的密码,即利用主密码将加
310
311密过的次密码解密出来并进行认证。
312
313
314
3154、try_mapped_pass
316
317
318
319这个选项指示本模块首先尝试使用映射过的密码,即利用主密码将加密过的次密码解密出来
320
321并进行认证。如果密码认证失败,则再提示用 户输入密码。
322
323
324
325密码映射的例子:
326
327
328
329下面是/etc/pam.conf中关于login服务的配置。这里login共有3种认证机制:Kerberos、UN
330
331IX和RSA认证,两个required控制标志表明用户必 须通过Kerberos认证和UNIX认证才能使用
332
333login服务,optional选项则说明RSA认证是可选的。首先用户输入主密码进行Kerberos认 证
334
335;use_mapped_pass选项指示UNIX认证模块利用主密码将用于UNIX认证的次密码解密出来并对
336
337该次密码进行认证;try_first_pass选项 指示RSA认证模块先使用第一个模块(即Kerberos
338
339模块)的密码作为进行认证的密码,当对该密码认证失败时才提示用户输入用于RSA认 证的
340
341次密码。
342
343login auth required pam_kerb_auth.so debug
344
345login auth required pam_unix_auth.so use_mapped_pass
346
347login auth optional pam_rsa_auth.so try_first_pass
348
349
350
351六、PAM API
352
353
354
3551、框架API:
356
357
358
359任何一个支持PAM的服务程序在进行认证时必须以pam_start( )开始进行初始化,最后以pam
360
361_end( )结束以便进行清理工作。
362
363
364
3652、认证管理API:
366
367
368
369pam_authenticate( )对用户名/密码进行认证。
370
371pam_setcred( )用来修改用户的秘密信息。
372
373
374
3753、帐户管理API:
376
377
378
379pam_acct_mgmt( )检查帐户本身是否有权限登录系统、帐户是否过期、帐户是否有登录时间
380
381限制等。
382
383
384
3854、密码管理API:
386
387
388
389pam_chauthtok( )修改用户的密码。
390
391
392
3935、会话管理API:
394
395
396
397一个会话以pam_open_session( )开始,最后以pam_close_session( )结束。
398
399
400
4016、其它:
402
403
404
405pam_get_item( )、pam_set_item( )用来读写PAM事务(transaction)的状态信息。
406
407pam_get_data( )、pam_set_data( )用来取得和设置PAM模块及会话的相关信息。
408
409pam_putenv( )、pam_getenv( )、pam_getenvlist( )用来读写环境变量。
410
411pam_strerror( )返回相关的错误信息。
412
413例子程序(摘自Sun的白皮书):
414
415
416
417下面的例子使用PAM API写了一个简单的login服务程序(注:这不是个完整的程序,所以省
418
419略了对pam_close_session的调用)。
420
421
422
423#include <security pam_appl.h="">
424
425
426
427/* 回调函数 */
428
429static int login_conv(int num_msg, struct pam_message **msg, struct pam_response
430
431**response, void *appdata_ptr);
432
433struct pam_conv pam_conv = {login_conv, NULL};
434
435pam_handle_t *pamh; /* 进行认证的PAM句柄 */
436
437
438
439void main(int argc, char *argv[], char **renvp)
440
441{
442
443/* 初始化,并提供一个回调函数 */
444
445if ((pam_start("login", user_name, &pam_conv, &pamh)) != PAM_SUCCESS)
446
447login_exit(1);
448
449
450
451/* 设置一些参数 */
452
453pam_set_item(pamh, PAM_TTY, ttyn);
454
455pam_set_item(pamh, PAM_RHOST, remote_host);
456
457
458
459while (!authenticated && retry < MAX_RETRIES)
460
461{
462
463status = pam_authenticate(pamh, 0); /* 密码认证管理,检查用户输入
464
465的密码是否正确 */
466
467authenticated = (status == PAM_SUCCESS);
468
469}
470
471
472
473if (status != PAM_SUCCESS)
474
475{
476
477fprintf(stderr,"error: %s\n", pam_strerror(pamh, status)); /* 显示错误原
478
479因 */
480
481login_exit(1);
482
483}
484
485
486
487/* 通过了密码认证之后再调用帐户管理API,检查用户帐号是否已经过期 */
488
489if ((status = pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS)
490
491{
492
493if (status == PAM_AUTHTOK_EXPIRED)
494
495{
496
497status = pam_chauthtok(pamh, 0); /* 过期则要求用户更改密码 */
498
499if (status != PAM_SUCCESS)
500
501login_exit(1);
502
503}
504
505}
506
507
508
509/* 通过帐户管理检查之后则打开会话 */
510
511if (status = pam_open_session(pamh, 0) != PAM_SUCCESS)
512
513login_exit(status);
514
515
516
517/* 设置用户组 */
518
519setgid(pwd->pw_gid);
520
521
522
523/*
524
525* Initialize the supplementary group access list before
526
527* pam_setcred because PAM modules might add groups
528
529* during the pam_setcred call
530
531*/
532
533initgroups(user_name, pwd->pw_gid);
534
535
536
537status = pam_setcred(pamh, PAM_ESTABLISH_CRED);
538
539if (status != PAM_SUCCESS)
540
541login_exit(status);
542
543
544
545/* 设置真实的用户ID(或者有效的用户ID)*/
546
547setuid(pwd->pw_uid);
548
549
550
551pam_end(pamh, PAM_SUCCESS); /* PAM事务的结束 */
552
553
554
555
556
557/*
558
559此处可用来实现与login有关的其它内容
560
561*/
562
563}
564
565
566
567/* 出错则清理现场并退出 */
568
569static void login_exit(int exit_code)
570
571{
572
573if (pamh)
574
575pam_end(pamh, PAM_ABORT);
576
577exit(exit_code);
578
579}
580
581
582
583
584
585/* 这个回调函数被PAM认证模块调用以便显示错误信息或者或者用来取得用户输入,采用图
586
587形界面的服务程序则应使用图形界面来取得 用户输入或显示提示信息*/
588
589int login_conv(int num_msg, struct pam_message **msg, struct pam_response **resp
590
591onse, void *appdata_ptr)
592
593{
594
595while (num_msg--)
596
597{
598
599switch (m->msg_style)
600
601{
602
603case PAM_PROMPT_ECHO_OFF:
604
605r->resp = strdup(getpass(m->msg));
606
607break;
608
609case PAM_PROMPT_ECHO_ON:
610
611(void) fputs(m->msg, stdout);
612
613r->resp = malloc(PAM_MAX_RESP_SIZE);
614
615fgets(r->resp, PAM_MAX_RESP_SIZE, stdin);
616
617/* add code here to remove \n from fputs */
618
619break;
620
621case PAM_ERROR_MSG:
622
623(void) fputs(m->msg, stderr);
624
625break;
626
627case PAM_TEXT_INFO:
628
629(void) fputs(m->msg, stdout);
630
631break;
632
633default:
634
635log_error();
636
637break;
638
639}
640
641}
642
643return (PAM_SUCCESS);
644
645}
646
647
648
649七、PAM SPI
650
651
652
653当服务程序(ftpd、telnetd等)调用PAM API函</security></anonymous@anonymous.com>