1 /* cvm/cvm-pwfile.c - Alternate passwd file CVM module
2 * Copyright (C) 2010 Bruce Guenter <bruce@untroubled.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18 #include <bglibs/sysdeps.h>
19 #include <errno.h>
20 #include <pwd.h>
21 #include <stdlib.h>
22 #include <string.h>
23
24 #include <bglibs/ibuf.h>
25 #include <bglibs/msg.h>
26 #include <pwcmp/client.h>
27
28 #include "module.h"
29
30 const char program[] = "cvm-pwfile";
31
32 static const char* pwfilename;
33
cvm_module_init(void)34 int cvm_module_init(void)
35 {
36 if ((pwfilename = getenv("CVM_PWFILE_PATH")) == 0) return CVME_CONFIG;
37 if (!pwcmp_start(getenv("CVM_PWFILE_PWCMP"))) return CVME_GENERAL;
38 return 0;
39 }
40
parse_rest(char * rest)41 static int parse_rest(char* rest)
42 {
43 /* Format: "UID:GID:NAME,other:DIR:SHELL" */
44 char* tmp;
45 cvm_fact_userid = strtoul(rest, &tmp, 10);
46 if (*tmp != ':') return 0;
47 rest = tmp + 1;
48
49 cvm_fact_groupid = strtoul(rest, &tmp, 10);
50 if (*tmp != ':') return 0;
51 rest = tmp + 1;
52
53 cvm_fact_realname = rest;
54 if ((tmp = strchr(rest, ',')) != 0) {
55 *tmp++ = 0;
56 rest = tmp;
57 }
58
59 if ((tmp = strchr(rest, ':')) == 0) return 0;
60 *tmp++ = 0;
61 cvm_fact_directory = rest = tmp;
62
63 if ((tmp = strchr(rest, ':')) == 0) return 0;
64 *tmp++ = 0;
65 cvm_fact_shell = rest = tmp;
66
67 cvm_fact_groupname = 0;
68 return 1;
69 }
70
71 static char* passwd;
72 static char* rest;
73 static str line;
74
cvm_module_lookup(void)75 int cvm_module_lookup(void)
76 {
77 ibuf pwfile;
78 long namelen;
79
80 if (cvm_module_credentials[CVM_CRED_ACCOUNT].s == 0)
81 return CVME_NOCRED;
82 passwd = 0;
83 namelen = cvm_module_credentials[CVM_CRED_ACCOUNT].len;
84
85 if (!ibuf_open(&pwfile, pwfilename, 0)) return CVME_IO;
86 while (ibuf_getstr(&pwfile, &line, LF)) {
87 line.s[--line.len] = 0;
88 if (strncasecmp(cvm_module_credentials[CVM_CRED_ACCOUNT].s, line.s, namelen) == 0
89 && line.s[namelen] == ':') {
90 passwd = line.s + namelen;
91 *passwd++ = 0;
92 break;
93 }
94 }
95 ibuf_close(&pwfile);
96 if (passwd == 0) return CVME_PERMFAIL;
97
98 if ((rest = strchr(passwd, ':')) == 0 || rest == passwd)
99 return CVME_PERMFAIL;
100 *rest++ = 0;
101 return 0;
102 }
103
cvm_module_authenticate(void)104 int cvm_module_authenticate(void)
105 {
106 CVM_CRED_REQUIRED(PASSWORD);
107 switch (pwcmp_check(cvm_module_credentials[CVM_CRED_PASSWORD].s, passwd)) {
108 case 0: return 0;
109 case -1: return CVME_IO | CVME_FATAL;
110 default: return CVME_PERMFAIL;
111 }
112 }
113
cvm_module_results(void)114 int cvm_module_results(void)
115 {
116 cvm_fact_username = line.s;
117 if (!parse_rest(rest)) return CVME_CONFIG;
118 return 0;
119 }
120
cvm_module_stop(void)121 void cvm_module_stop(void)
122 {
123 pwcmp_stop();
124 }
125