forked from donapieppo/libnss-ato
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlibnss_ato.c
152 lines (121 loc) · 3.13 KB
/
libnss_ato.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
* libnss_ato.c
*
* Nss module to map every requested user to a fixed one.
* Ato stands for "All To One"
*
* Copyright (c) Pietro Donatini ([email protected]), 2007.
*
* this product may be distributed under the terms of
* the GNU Lesser Public License.
*
* version 0.2
*
* CHANGELOG:
* strip end of line in reading /etc/libnss-ato
* suggested by Kyler Laird
*
* TODO:
*
* check bugs
*
*/
#include <nss.h>
#include <pwd.h>
#include <shadow.h>
#include <string.h>
#include <stdio.h>
/* for security reasons */
#define MIN_UID_NUMBER 500
#define MIN_GID_NUMBER 500
#define CONF_FILE "/etc/libnss-ato.conf"
/*
* the configuration /etc/libnss-ato.conf is just one line
* with the local user data as in /etc/passwd. For example:
* dona:x:1001:1001:P D ,,,:/home/dona:/bin/bash
* Extra lines are comments (not processed).
*/
struct passwd *
read_conf()
{
FILE *fd;
struct passwd *conf;
if ((fd = fopen(CONF_FILE, "r")) == NULL ) {
return NULL;
}
conf = fgetpwent(fd);
if ( conf->pw_uid < MIN_UID_NUMBER )
conf->pw_uid = MIN_UID_NUMBER;
if ( conf->pw_gid < MIN_GID_NUMBER )
conf->pw_gid = MIN_GID_NUMBER;
fclose(fd);
return conf;
}
/*
* Allocate some space from the nss static buffer. The buffer and buflen
* are the pointers passed in by the C library to the _nss_ntdom_*
* functions.
*
* Taken from glibc
*/
static char *
get_static(char **buffer, size_t *buflen, int len)
{
char *result;
/* Error check. We return false if things aren't set up right, or
* there isn't enough buffer space left. */
if ((buffer == NULL) || (buflen == NULL) || (*buflen < len)) {
return NULL;
}
/* Return an index into the static buffer */
result = *buffer;
*buffer += len;
*buflen -= len;
return result;
}
enum nss_status
_nss_ato_getpwnam_r( const char *name,
struct passwd *p,
char *buffer,
size_t buflen,
int *errnop)
{
struct passwd *conf;
if ((conf = read_conf()) == NULL) {
return NSS_STATUS_NOTFOUND;
}
*p = *conf;
/* If out of memory */
if ((p->pw_name = get_static(&buffer, &buflen, strlen(name) + 1)) == NULL) {
return NSS_STATUS_TRYAGAIN;
}
/* pw_name stay as the name given */
strcpy(p->pw_name, name);
if ((p->pw_passwd = get_static(&buffer, &buflen, strlen("x") + 1)) == NULL) {
return NSS_STATUS_TRYAGAIN;
}
strcpy(p->pw_passwd, "x");
return NSS_STATUS_SUCCESS;
}
enum nss_status
_nss_ato_getspnam_r( const char *name,
struct spwd *s,
char *buffer,
size_t buflen,
int *errnop)
{
/* If out of memory */
if ((s->sp_namp = get_static(&buffer, &buflen, strlen(name) + 1)) == NULL) {
return NSS_STATUS_TRYAGAIN;
}
strcpy(s->sp_namp, name);
if ((s->sp_pwdp = get_static(&buffer, &buflen, strlen("*") + 1)) == NULL) {
return NSS_STATUS_TRYAGAIN;
}
strcpy(s->sp_pwdp, "*");
s->sp_lstchg = 13571;
s->sp_min = 0;
s->sp_max = 99999;
s->sp_warn = 7;
return NSS_STATUS_SUCCESS;
}