首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 操作系统-> Linux教程
linux shadow-password-howto - 8. 加入 shadow 支援
作者:网友供稿 点击:19
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 

新增支援 shadow 程式事实上是很直接的。 唯一的问题是程式需要以 root (或 SUID root) 权限执行,这样才可以存取 /etc/shadow 档。 

这显示一个大问题: 当建立 SUID 程式时需要很小心依照程式运作。举例说明: 如果以个程式有 shell escape,如果程式本身是 SUID root 将不需要以 root 方式呈现。 

对程式新增支援 shadow 而言,它可以检查密码,但不需以 root 权限执行,而是以 SUID shadow 取代执行比较安全。 xlock 程式就是一个例子。 

接下来□例介绍, pppd-1.2.1d 已经以 SUID as root 方式执行,所以新增 shadow 支援应该不会使程式产生任何影响。 



8.1 标头档(Header files) 
标头档应存在 /usr/include/shadow。 应该有一个 /usr/include/shadow.h档,但是它将 symbolic link 到 /usr/include/shadow/shadow.h。 

为了新增支援 shadow 程式,你需要 include 标头档: 


#include 
#include 



8.2 libshadow.a 函式库(library) 
当你安装 Shadow Suite, libshadow.a 档被建立和安装在 /usr/lib 目录。 

当编译一个 shadow support 程式,linker 需要包括 libshadow.a 函式库进入链结。 


执行如下: 

gcc program.c -o program -lshadow

然而,就像我们接下来要看的例子,大部分大程式使用 Makefile 且通常有变数呼叫 LIBS=... 需要被修改。 


8.3 Shadow 结构(Structure) 
libshadow.a 函式库对它从 /etc/shadow 档接收资讯使用结构化呼叫。这是从 /usr/include/shadow/shadow.h 标头档的 spwd 结构定义: 



--------------------------------------------------------------------------------

struct spwd
{
  char *sp_namp;                /* login name */
  char *sp_pwdp;                /* encrypted password */
  sptime sp_lstchg;             /* date of last change */
  sptime sp_min;                /* minimum number of days between changes */
  sptime sp_max;                /* maximum number of days between changes */
  sptime sp_warn;               /* number of days of warning before password
                                   expires */
  sptime sp_inact;              /* number of days after password expires
                                   until the account becomes unusable. */
  sptime sp_expire;             /* days since 1/1/70 until account expires
*/
  unsigned long sp_flag;        /* reserved for future use */
};


--------------------------------------------------------------------------------

Shadow Suite 可以放除了编码密码之外的资料到 sp_pwdp 栏位。密码栏位可包括: 

username:Npge08pfz4wuk;@/sbin/extra:9479:0:10000::::

这表示一个额外的密码, /sbin/extra 程式应该被更多的权限呼叫。 程式的呼叫需取得使用者名称和指出为何需被呼叫的 switch才可通过。 查看 /usr/include/shadow/pwauth.h 和原始码 pwauth.c 获得更多资讯。 

为何我们应使用 pwauth 去表示真正的权限,这是什麽意思,它将使第二组权限也跑得很好。 

Shadow Suite 作者指出因为大部分存在的程式都不这麽作罗,所以 Shadow Suite未来的版本将移除。 


8.4 Shadow 函式(Functions) 
shadow.h 包含 libshadow.a 函式库: 


--------------------------------------------------------------------------------

extern void setspent __P ((void));
extern void endspent __P ((void));
extern struct spwd *sgetspent __P ((__const char *__string));
extern struct spwd *fgetspent __P ((FILE *__fp));
extern struct spwd *getspent __P ((void));
extern struct spwd *getspnam __P ((__const char *__name));
extern int putspent __P ((__const struct spwd *__sp, FILE *__fp));


--------------------------------------------------------------------------------

我们将使用的□例程式是: getspnam 将对供应名称恢复对我们 spwd 结构。 


8.5 □例 
这是一个□例描述新增 shadow 支援程式,但预设值并没有。 


本□例使用 Point-to-Point Protocol Server (pppd-1.2.1d),它有个模式是表示 从 /etc/passwd 档取代 PAP 或 CHAP 档使用帐号密码的 PAP 权限,你将不需要在 pppd-2.2.0 加这些程式码,因为它已经存在罗。 



pppd 的未来大致上不会被使用很多,但是如果你安装 Shadow Suite,储存在 /etc/passwd 档的密码将无法运作。 

在 pppd-1.2.1d 权限使用的程式码是位在 /usr/src/pppd-1.2.1d/pppd/auth.c 档。 

接下来程式码需要被加在所有其他 #include 指令档案的最上头,我们将注意有环境指令的 #includes。 



--------------------------------------------------------------------------------

#ifdef HAS_SHADOW
#include 
#include 
#endif


--------------------------------------------------------------------------------

接下来要做的事情是变更实际码, 我们将变更 auth.c 档。 

变更前 auth.c 档 function 为: 


--------------------------------------------------------------------------------

/*
 * login - Check the user name and password against the system
 * password database, and login the user if OK.
 *
 * returns:
 *      UPAP_AUTHNAK: Login failed.
 *      UPAP_AUTHACK: Login succeeded.
 * In either case, msg points to an appropriate message.
 */
static int
login(user, passwd, msg, msglen)
    char *user;
    char *passwd;
    char **msg;
    int *msglen;
{
    struct passwd *pw;
    char *epasswd;
    char *tty;

    if ((pw = getpwnam(user)) == NULL) {
        return (UPAP_AUTHNAK);
    }
     /*
     * XXX If no passwd, let them login without one.
     */
    if (pw->pw_passwd == \0) {
        return (UPAP_AUTHACK);
    }

    epasswd = crypt(passwd, pw->pw_passwd);
    if (strcmp(epasswd, pw->pw_passwd)) {
        return (UPAP_AUTHNAK);
    }

    syslog(LOG_INFO, "user %s logged in", user);

    /*
     * Write a wtmp entry for this user.
     */
    tty = strrchr(devname, /);
    if (tty == NULL)
        tty = devname;
    else
        tty++;
    logwtmp(tty, user, "");             /* Add wtmp login entry */
    logged_in = TRUE;

    return (UPAP_AUTHACK);
}


--------------------------------------------------------------------------------

使用者的密码被放在 pw->pw_passwd,所以我们需新增 getspnam function,这将会把密码放到 spwd->sp_pwdp。 

我们将新增 pwauth function 来表示真正的权限。 这将在 shadow 档设定时自动产生第二个权限。 

变更为可以支援 shadow 後的 auth.c function: 



--------------------------------------------------------------------------------

/*
 * login - Check the user name and password against the system
 * password database, and login the user if OK.
 *
 * This function has been modified to support the Linux Shadow Password
 * Suite if USE_SHADOW is defined.
 *
 * returns:
 *      UPAP_AUTHNAK: Login failed.
 *      UPAP_AUTHACK: Login succeeded.
 * In either case, msg points to an appropriate message.
 */
static int
login(user, passwd, msg, msglen)
    char *user;
    char *passwd;
    char **msg;
    int *msglen;
{
    struct passwd *pw;
    char *epasswd;
    char *tty;

#ifdef USE_SHADOW
    struct spwd *spwd;
    struct spwd *getspnam();
#endif

    if ((pw = getpwnam(user)) == NULL) {
        return (UPAP_AUTHNAK);
    }

#ifdef USE_SHADOW
        spwd = getspnam(user);
        if (spwd)
                pw->pw_passwd = spwd->sp-pwdp;
#endif
 
     /*
     * XXX If no passwd, let NOT them login without one.
     */
    if (pw->pw_passwd == \0) {
        return (UPAP_AUTHNAK);
    }
#ifdef HAS_SHADOW
    if ((pw->pw_passwd && pw->pw_passwd[0] == @
         && pw_auth (pw->pw_passwd+1, pw->pw_name, PW_LOGIN, NULL))
        || !valid (passwd, pw)) {
        return (UPAP_AUTHNAK);
    }
#else
    epasswd = crypt(passwd, pw->pw_passwd);
    if (strcmp(epasswd, pw->pw_passwd)) {
        return (UPAP_AUTHNAK);
    }
#endif

    syslog(LOG_INFO, "user %s logged in", user);

    /*
     * Write a wtmp entry for this user.
     */
    tty = strrchr(devname, /);
    if (tty == NULL)
        tty = devname;
    else
        tty++;
    logwtmp(tty, user, "");             /* Add wtmp login entry */
    logged_in = TRUE;

    return (UPAP_AUTHACK);
}


--------------------------------------------------------------------------------

严谨的□例将启发我们在作其他改变的帮助。 原始的版本如果在 /etc/passwd 档没有任何密码,可允许存取传回的 UPAP_AUTHACK 。这是不好的,因为签入的使用是使用一个允许存取 PPP process的帐号,然後检查帐号密码,该帐号密码是由 RAP 、在 /etc/passwd 档的帐号和 /etc/shadow 档的密码供应。 


所以如果我们设定原本版本对每个使用者,如 ppp 可以在 shell 执行,然後任何人可以获得 ppp 链结透过设定他们对使用者 ppp 的 PAP 和 null 的密码。 


我们修正 UPAP_AUTHNAK 取代 UPAP_AUTHACK 如果密码栏位是空的。 

有趣的是 pppd-2.2.0 有相同的问题。 

接下来我们需要变更 Makefile 以便让两件事发生: 

USE_SHADOW 必须被重新定义且libshadow.a 需要被新增到链结 process。 


编辑 Makefile 且新增: 

LIBS = -lshadow

然後我们找到这一行: 

COMPILE_FLAGS = -I.. -D_Linux_=1 -DGIDSET_TYPE=gid_t

然後改变它变成: 

COMPILE_FLAGS = -I.. -D_linux_=1 -DGIDSET_TYPE=gid_t -DUSE_SHADOW

现在执行 make 跟 install. 


文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·最简单的Struts程序-JSP教程,资料/其它
·利用激光供电的光电电流互感器
·java到structs-JSP教程,Java技巧及代码
·鼠标样式,整体背景图,滚动条的效果(网页效果)-ASP教程,ASP应用
·ASP中正则表达式的应用-ASP教程,正则表达式
·XML应用-利用XML 与XSL-.NET教程,XML应用
·.net 下用javascript调用webservice-.NET教程,Web Service开发
·Asp无组件上传进度条解决方案-ASP教程,组件开发
·破译动网验证码的简单方法-.NET教程,评论及其它
·linux系统文件命令精通指南(上)
最新文章
·mashups+ajax打造全新web开发_ajax教程
·windows vista系统中写字板应用全攻略_windows vista
·adsense单价持续低迷的解读_网赚技巧
·google反作弊小组成员专访_站长访谈
·端午议话:谈网站的特色_站长心得
·浅谈我的十点论坛管理经验_站长心得
·如何针对msn的onpage进行网页优化_站长心得
·用google 搜索框黏住易变的访问者_google推广
·google关键词广告每次点击付费(ppc)术语表_google推广
·确保万无一失的google 关键词广告公式_google推广
相关主题
  • linux操作系统上摄像头的使用小技巧_linux教程
  • linux下mysql的一点基本用法_数据库教程
  • linux攻略 dns服务器安装配置方法详细介绍_linux教程
  • linux学习(远程控制跟ip地址配置)_linux教程
  • linux系统下如何加载u盘或移动硬盘_linux教程
  • 西部数码虚拟主机

    友情链接
    CNNIC 西部数码
    万网 自助建站
    虚拟主机 asp空间
    域名注册 域名
    域名申请 主页空间
    论坛空间 网站空间
    国际域名 虚拟空间
    空间租用 DDOS防火墙
    成都主机托管 四川主机托管
    主机租用 服务器租用
    网站目录 自助建站
    虚拟主机 网址大全
    软件下载
    自助链接
    虚拟主机资讯 特价虚拟主机
    版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
    关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
    特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
    发表评论 打印  刷新     关闭