2013年10月22日 星期二

[Linux C]-一行指令建立帳號、更新密碼 (需setuid) 於 Ubuntu 12.04

[Linux C]-一行指令建立帳號、更新密碼 (需setuid) 於 Ubuntu 12.04



拷貝來源: http://www.itneng.com/thread-2398-1-1.html


最近有需求要幫系統加入新增帳號、修改帳密的流程,所以想著想著,就蹦出了一支 C 程式,透過 setuid 的方式,終於可以完成這項工作 (經高手指點,bash 無法被 setuid 使用,也就是配置完後無法達成想要的結果,可以在 script 裡打 id 指令)

相關 Unix 指令回顧:

一行指令新增帳號
$ sudo adduser --quiet --gecos "" --disabled-login --no-create-home --shell "/usr/sbin/nologin" tester
一行指令更新密碼
$ echo "tester:password" | chpasswd
檢查使用者是否存在
$ getent passwd tester
程式碼:









#include <stdio.h>


#include <stdlib.h>


#include <string.h>


 


#include <sys/types.h>


#include <unistd.h>


 


#define CMD_ADDUSER "sudo adduser --quiet --gecos \"\" --disabled-login --no-create-home --shell \"/usr/sbin/nologin\""


#define CMD_CHECK_USER_EXISTS "getent passwd"


#define MAX_BUFFER_LINE 1024


intmain(int argc,char*argv[])


{


   char buf[MAX_BUFFER_LINE+1], pass[MAX_BUFFER_LINE+1],*cmd;


   FILE*fp;


   setuid(0);// use root


   //system("id");


   if( argc <3)


   {


      fprintf(stderr,"Usage> %s username [ - | password]\n\t%s username -\t\t(read password from stdin)\n\t%s username password\n\n\tothers: sudo chown root %s && sudo chmod 4755 %s\n", argv[0], argv[0], argv[0], argv[0], argv[0]);


      exit(1);


   }


 


   memset( buf,0, MAX_BUFFER_LINE +1);


   memset( pass,0, MAX_BUFFER_LINE +1);


   if( argv[2][0]!='-')


   {


      strncpy( pass, argv[2], MAX_BUFFER_LINE );


      pass[MAX_BUFFER_LINE]='\0';


   }


   elseif(!feof(stdin)&&fgets( pass, MAX_BUFFER_LINE,stdin)>0)


   {


      //printf("Pass:[%s]\n",pass);


   }


 


   if(strlen(pass)<1)


   {


      fprintf(stderr,"Error @ Init: password is empty\n");


      exit(1);


   }


 


   // check account exists


   cmd = buf;


   snprintf( buf, MAX_BUFFER_LINE,"%s%s", CMD_CHECK_USER_EXISTS, argv[1]);


   fp = popen( cmd ,"r");


 


   memset( buf,0, MAX_BUFFER_LINE +1);


   fgets( buf, MAX_BUFFER_LINE, fp );


   pclose(fp);


 


   if(!strlen(buf))// create the account if not exists


   {


      // add account


      memset( buf,0, MAX_BUFFER_LINE +1);


      cmd = buf;


      snprintf( buf, MAX_BUFFER_LINE,"%s%s", CMD_ADDUSER, argv[1]);


      pclose( popen( cmd ,"r"));


 


      // query the account


      memset( buf,0, MAX_BUFFER_LINE +1);


      cmd = buf;


      snprintf( buf, MAX_BUFFER_LINE,"%s%s", CMD_CHECK_USER_EXISTS, argv[1]);


      fp = popen( cmd ,"r");


      memset( buf,0, MAX_BUFFER_LINE +1);


      fgets( buf, MAX_BUFFER_LINE, fp );


      pclose(fp);


 


      if(!strstr( buf, argv[1]))// user is not created


      {


         printf("Error @ create an account: user cannot be created\n");


         exit(1);


      }


 


      // change password


      memset( buf,0, MAX_BUFFER_LINE +1);


      cmd = buf;


      snprintf( buf, MAX_BUFFER_LINE,"echo \"%s:%s\" | chpasswd ", argv[1], pass );


      fp = popen( cmd ,"r");


      memset( buf,0, MAX_BUFFER_LINE +1);


      fgets( buf, MAX_BUFFER_LINE, fp );


      pclose(fp);


      if(!strlen(buf))


         printf("OK\n");


   }


   elseif(strstr( buf,"/bin/false")||strstr( buf,"/nologin"))// change password


   {


      // change password


      memset( buf,0, MAX_BUFFER_LINE +1);


      cmd = buf;


      snprintf( buf, MAX_BUFFER_LINE,"echo \"%s:%s\" | chpasswd ", argv[1], pass );


      fp = popen( cmd ,"r");


      memset( buf,0, MAX_BUFFER_LINE +1);


      fgets( buf, MAX_BUFFER_LINE, fp );


      pclose(fp);


      if(!strlen(buf))


         printf("OK\n");


   }


   else


   {


      printf("SKIP @ cannot change the password for '%s'.\n", argv[1]);


   }


   return0;


}


 



暫時把這段程式定位:

可以新增 nologin 帳號
可以修改 nologin 帳號的密碼
用法:

$ gcc main.c
$ sudo chown root ./a.out && sudo chmod 4755 ./a.out
$ ./a.out new_account new_password


沒有留言:

張貼留言