Linux Cプログラミング--プロセス紹介6-プロセスの各種識別

4909 ワード

ここでは、プロセスについて説明します.
1.プロセスのユーザーID番号
2.プロセスID番号
プロセスのユーザーID
Linux/Unixプロセスは、3種類のユーザーIDに関連しています.
1、実際のユーザID(real user id,RUID):当該プロセスの作成者であるユーザIDは、プロセスの実行者ともいえる.このIDはrootユーザーのみが変更できます.
2.有効ユーザーID(effective user id,EUID):このIDはユーザープロセスが操作を実行する権限を識別するために使用される.一般ユーザは、EUIDをRUIDまたはSUIDに設定することができ、一般ユーザは、EUIDを任意の正当なUIDに設定することができる.
3、設定ユーザID(saved set-user-id、SUID)を保存する:このIDは主にプロセスが有効なユーザID(EUID)を切り替える時に使用する.set-uid-bitが設定されていない実行可能プログラム(ファイル)の場合、その対応プロセスの保存設定ユーザID(SUID)はその実際のユーザIDである.set-uid-bitが設定されたプログラム(ファイル)に対しては、その実行可能ファイルのファイル所有者ユーザID(SUID)が対応する格納設定ユーザID(SUID)となる.またSUIDは、その値が変更されたときに新たなSUID値が記録される.
実行可能なバイナリファイルで、set-use-id bitが設定されている場合、プログラムが実行されると、対応するプロセスの有効ユーザID(EUID)がファイルのファイル所有者ユーザIDとなる.これはファイルアクセスディレクトリに記載されており、参照できます.
 
APUE 2では、プロセスに関連する3種類のユーザIDについて詳細な説明があり、その内容に合わせていくつかの点を整理する.
1、プロセスにスーパーユーザー特権がある場合、setuid(uid)関数により実際のユーザーID、有効なユーザーID、および保存設定ユーザーIDをuidに設定することができる.このときuidの値がRUID,EUID,SUIDと等しいかどうかは気にしない(スーパーユーザは牛叉であり,何かuidを設定したいなら何かユーザuidを設定する).特権ユーザがsetuidを実行するとRUID,EUID,SUIDがすべてuidに設定され,uidがユーザ非特権に対応すると,このような操作を実行してスーパーユーザに戻ることができなくなる(通常の権限に置き換えられた).
2、スーパーユーザ特権のない一般ユーザは、setuid(uid)を呼び出すことにより、uid=RUID、またはSUIDの場合のみ、その有効ユーザID(EUID)をuidに設定することができ、この場合RUID、SUIDの値に影響を与えない.
3、ユーザーがsetuid(uid)でプロセスのUIDを設定した場合、uidが上記のルールを満たしていない場合、setuid関数の実行に失敗し、EPERMエラーを返す.
 
上記の説明から、
1.プロセスの実際のユーザID(RUID)を変更できるのはスーパーユーザのみであり、他のユーザはRUIDを変更できない.
2、プログラムファイルにset-user-id bitが設定されている場合のみ、EUIDはプログラムファイルの所有者ユーザIDに等しく、設定されていない場合、EUIDはユーザのRUIDとなる.プロセスの有効ユーザID(EUID)は、いつでもsetuidで実際のユーザID(RUID)に設定したり、ユーザID(SUID)を指して保存したりすることができますが、EUIDを任意のuid(すなわち、即時値)に設定することはできません.
3、保存設定ユーザID(SUID)は、ユーザの有効ユーザID(EUID)からコピーされたものである.
以下の表は、3つのユーザIDを変更する異なる方法である(APUE 2)
 
-----------------------------------------------------------------------
     |                   exec                    |    setuid(uid)
 ID  ------------------------------------------------------------------
     | set-user-id bit off | set-user-id bit on  | superuser|normal user
------------------------------------------------------------------------
RUID|不変|不変|設定をuid|不変
EUID|不変|プログラムファイルRUID|uid|uidに設定
SUID|EUIDからコピー|EUIDからコピー|uidに設定|変更なし
------------------------------------------------------------------------
また、seteuidにより、セットアッププロセスの有効ユーザID(EUID)を以下のようにすることができる.
1.非特権ユーザがプロセス有効ユーザID(EUID)を介して実際のユーザID(RIIOD)に設定するか、または設定ユーザID(SUID)を保存する.
2、1人の特権ユーザに対して、有効ユーザID(EUID)をuid(uidは任意の値であり、そのEUIDにのみ影響し、他のID:RUID、SUIDを変更しない)に設定することができる
三、関連API
    1、int setuid(uid_t u i d) ;     2、int setgid(gid_t g i d) ;
-----ユーザのRUID/RGIDを設定(特権ユーザはEUID/EGID、SUID/SGIDに関与する).
    3、int setreuid(uid_t ru i d, uid_t e u i d) ;     4、int setregid(gid_t rg i d, gid_t e g i d) ;
   
------プロセスの実際のユーザ(グループ)と有効なユーザ(グループ)IDを交換する.
 
    5、int seteuid(uid_t u i d) ;     6、int setegid(gid_t g i d) ;
   
------プロセス有効ユーザー(グループ)IDを設定.
 
    7、uid_t getuid(void);      8、uid_t geteuid(void);  
 
-------ユーザの実際のユーザID(RUID)/有効ユーザID(EUID)を取得する.
 
    9、gid_t getgid(void);     10、gid_t getegid(void);
 
-------ユーザ実ユーザグループID(RUID)/有効ユーザグループID(EGID)を取得する.
次に、上記のシステム関数の使い方を説明する例を示します.
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
	int i,ret;
	if(argc!=2)
	{
		printf("Usage %s num
",argv[0]); exit(1); } i=atoi(argv[1]); printf("Before uid = %d ,euid = %d
",getuid(),geteuid()); ret=setuid(i); printf("After uid = %d ,euid =%d
",getuid(),geteuid()); printf("ret=%d
",ret); }

プロセスID
Linuxでの主なプロセス識別子は、プロセス番号(PID)とその親プロセス(PPID)である.PIDとPPIDはいずれも非ゼロの正の整数であり、linuxで現在のプロセスPIDとPPIDを取得するシステム呼び出し関数はgetpidとgetppidである.
getpidシステム呼び出しの説明:
必要なヘッダファイル
#include
関数の機能:
現在のプロセスのプロセス番号を取得
関数のプロトタイプ:
int getpid();
関数の入力値:
なし
関数の戻り値
現在のプロセスのプロセス番号を正常に返し、エラーをperrorに含めることに失敗しました.
コメント:
 
getppidシステム呼び出しの説明:
必要なヘッダファイル
#include
関数の機能:
現在のプロセスの親プロセス番号を取得
 
関数のプロトタイプ:
int getppid();
関数の入力値:
なし
関数の戻り値
現在のプロセスの親プロセス番号を正常に返し、エラーをperrorに含めることに失敗しました.
コメント:
 
次に、実装例を示します.
説明:システム内のプロセス識別番号は一意であるため、プロセス識別番号を使用して一時ファイルに名前を付けることができます.次に、実装を示します.
#include <sys/types.h>
#include <stdio.h>

char file[20],string[8];
char *tmp="./tmp.";
int main()
{
	char *s;
	int fd;
	s=(char *)malloc(100);
	sprintf(s,"%d",getpid());
	printf("pid is %s
",s); strcpy(file,tmp); strcat(file,s); if((fd=creat(file,0644))==-1) { fprintf(stderr,"file: %s create failed.
",file); exit(1); } write(fd,"TMP file
",9); close(fd); exit(0); }