File: checkpassword-pam.c

package info (click to toggle)
fgetty 0.7-7
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye
  • size: 260 kB
  • sloc: ansic: 1,516; makefile: 236
file content (74 lines) | stat: -rw-r--r-- 2,112 bytes parent folder | download | duplicates (6)
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
#include <string.h>
#include <unistd.h>
#include <pwd.h>

extern char** environ;

unsigned int fmt_ulong(char *dest,unsigned long i) {
  register unsigned long len,tmp,len2;
  /* first count the number of bytes needed */
  for (len=1, tmp=i; tmp>9; ++len) tmp/=10;
  if (dest)
    for (tmp=i, dest+=len, len2=len+1; --len2; tmp/=10)
      *--dest = (tmp%10)+'0';
  return len;
}

int main(int argc,char* argv[]) {
  char buf[513];
  char* last;
  int len;
  char *login,*ptr;
  struct passwd *pw;

  if (!argv[1]) return 2;
  for (len=0; len<512; ) {
    int tmp;
    tmp=read(3,buf+len,512-len);
    if (tmp==-1) return 111;
    if (tmp==0) break;
    len+=tmp;
  }
  close(3);
  buf[len]=0; last=buf+len;
  login=buf;
  if ((pw=getpwnam(login))) {
    ptr=login+strlen(login)+1;
    if (!authenticate_using_pam("login", login, ptr)) {
      char **env,**ep, *eptty;
      char buf[100];
      for (len=0; environ[len]; ++len) ;
      env=alloca((len+4)*sizeof(char*));
      ep=env;
      for (len=0; environ[len]; ++len) {
	if (!strncmp(environ[len],"USER=",5)) continue;
	if (!strncmp(environ[len],"HOME=",5)) continue;
	if (!strncmp(environ[len],"SHELL=",6)) continue;
	if (!strncmp(environ[len],"UID=",4)) continue;
	*ep=environ[len]; ++ep;
      }
      *ep=alloca(strlen(pw->pw_shell)+7); strcat(strcpy(*ep,"SHELL="),pw->pw_shell); ++ep;
      *ep=alloca(strlen(login)+6); strcat(strcpy(*ep,"USER="),login); ++ep;
      *ep=alloca(strlen(pw->pw_dir)+7); strcat(strcpy(*ep,"HOME="),pw->pw_dir); ++ep;
      strcpy(buf,"UID=");
      buf[4+fmt_ulong(buf+4,pw->pw_uid)]=0;
      *ep=buf; ++ep;
      *ep=0;

      ptr+=strlen(ptr)+1;	/* skip password */

      if (initgroups(pw->pw_name,pw->pw_gid)==-1) return 1;
/*      if (setgroups(1,&pw->pw_gid)==-1) return 1; */
      if (setgid(pw->pw_gid)==-1) return 1;
      if (ptr) {
	ptr+=strlen(ptr)+1;		/* skip timestamp */
	if (ptr>=last) ptr=0;
      }
      if (!ptr || strcmp(ptr,"nosetuid")) if (setuid(pw->pw_uid)==-1) return -1;
      if (chdir(pw->pw_dir)==-1) return 111;
      execve(argv[1],argv+1,env);
      return 111;
    }
  }
  return 1;
}