-
Notifications
You must be signed in to change notification settings - Fork 2
/
libnss_pool.c
114 lines (95 loc) · 2.8 KB
/
libnss_pool.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
/*
* libnss_pool.c
* Author: Marcin Stolarek ([email protected])
*/
#include <nss.h>
#include <pwd.h>
#include <shadow.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
//This defines the maximal size of the pool stored in /etc/pool-passwd
#define MAX_POOL_SIZE 20
//poolPasswd file
#define POOLPASSWD "/etc/pool-passwd"
enum nss_status
_nss_pool_getpwnam_r( const char *name,
struct passwd *p,
char *buffer,
size_t buflen,
int *errnop)
{
FILE * fd, * log;
struct passwd *it;
short created=0;
fd=fopen(POOLPASSWD,"r");
if(fd==NULL) {
return NSS_STATUS_NOTFOUND;
}
log=fopen("/tmp/debug","w+");
setbuf(log,NULL);
*buffer=NULL;
while ( (it=fgetpwent(fd)) != NULL) {
fprintf(log,"Read line: %s\n",it->pw_name);
if(!strcmp(name,it->pw_name) && !(strcmp("x",it->pw_passwd)) && !created ) {
fprintf(log,"Match %s \n",it->pw_name);
*p=*it;
//entry was there no need to process further
fclose(log);
return NSS_STATUS_SUCCESS;
}
//if passwd set to ! then it means that entry is empty and can be used for new user
else if(!strcmp("!",it->pw_passwd) && !created ) {
fprintf(log,"new %s \n",it->pw_name);
strcpy(it->pw_name,name); //this may be an issue if previous login name was shorter then new one
fprintf(log,"new %s \n",it->pw_name);
strcpy(it->pw_passwd,"x");
*p=*it;
created=1;
}
fprintf(log,"snprintf, when strlen(buffer)=%d and buflen=%d\n",(int)strlen(buffer),(int)buflen);
fprintf(log,"Adding to pool-passwd: %s:%s:%d:%d:%s:%s:%s\n",it->pw_name,it->pw_passwd,it->pw_uid,it->pw_gid,it->pw_gecos,it->pw_dir,it->pw_shell);
int howLong=snprintf(buffer+strlen(buffer),buflen,"%s:%s:%d:%d:%s:%s:%s\n",it->pw_name,it->pw_passwd,it->pw_uid,it->pw_gid,it->pw_gecos,it->pw_dir,it->pw_shell);
fprintf(log,"checking buffer\n");
if(howLong+1>buflen) {
fprintf(log,"try again\n");
fclose(log);
return NSS_STATUS_TRYAGAIN;
}
}
fclose(fd);
if(!created) {
return NSS_STATUS_NOTFOUND;
}
//If we are here it means that new user was created (name changed) in pool
fd=fopen(POOLPASSWD,"w");
fprintf(fd,"%s",buffer);
fclose(fd);
fclose(log);
return NSS_STATUS_TRYAGAIN; //Means that there are no more entries, we don't implement users enumeration
}
enum nss_status
_nss_pool_getpwuid_r(uid_t uid, struct passwd *p,
char *buf, size_t buflen, struct passwd **result)
{
FILE * fd, * log;
struct passwd *it;
fd=fopen(POOLPASSWD,"r");
if(fd==NULL) {
return NSS_STATUS_NOTFOUND;
}
log=fopen("/tmp/debugUid","w+");
setbuf(log,NULL);
while( (it=fgetpwent(fd)) != NULL) {
fprintf(log,"%s\n",it->pw_name);
if(it->pw_uid==uid) {
*p=*it;
fclose(log);
fclose(fd);
return NSS_STATUS_SUCCESS;
}
}
fclose(log);
fclose(fd);
return NSS_STATUS_NOTFOUND;
}